1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-18 14:27:39 +03:00

Compare commits

...

27 Commits

Author SHA1 Message Date
mpv
3abb040ed6 0031153: Visualization - Non clear highlighting of selected trihedron elements.
Revert not needed changes in AIS_InteractiveContext.cxx, that can be applied only on the newest OCCT.
2019-12-17 17:26:21 +03:00
jgv
d7cb2d422a 0031187: Modeling Algorithms - Regression relatively 7.3.0. Unify same domain algorithm produces invalid shape.
Modify the local function ReconstructMissedSeam to build new seam edges correctly.
2019-12-17 14:26:18 +03:00
vsv
eaee247ad9 0031153: Visualization - Non clear highlighting of selected trihedron elements
AIS_Trihedron - removed extra fields holding highlight styles; standard styles are now used instead;
fixed unexpected modification of global aspects;
fixed unhighligting of selected plane within Shaded trihedron.

AIS_InteractiveContext now sets highlight color to highlight aspects, not only base color to drawer itself.

# Conflicts:
#	src/AIS/AIS_Trihedron.cxx
2019-12-11 16:21:05 +03:00
jgv
009f94f4ee 0031066: Infinite loop in ShapeUpgrade_UnifySameDomain
Modification in local static method TransformPCurves - compute real U And V bounds of a face and use them in further computations.
2019-11-22 14:50:51 +03:00
jgv
63bf235463 0030927: Modeling Algorithms - UnifySameDom looses the Closed flag for wires
Add setting the Closed flag for a new wire
2019-11-22 14:50:34 +03:00
emv
faf34b5b67 0030914: Modeling Algorithms - Improve performance of UnifySameDom algorithm for specific case with many edges
Use cached containers to find the necessary shapes.
2019-11-22 14:50:16 +03:00
emv
4a092ef299 0030905: Modeling Algorithms - Faulty shapes in UnifySameDomain
Make face FORWARD before adding wire in it.
2019-11-22 14:49:33 +03:00
vsv
c9fd622676 0031153: Non clear highlighting of selected trihedron elements 2019-11-12 13:28:20 +03:00
emv
1630119c3a ref to 0029711: General Fuse operation produces invalid result
Avoid usage of uninitialized variable.
2019-09-23 11:13:57 +03:00
emv
10666b7e85 0030760: Modeling Algorithms - Intersection fails in Occt 7.3.0
Use FORWARD orientation of edges and face when attaching pcurve from one edge to another.
Test case for the issue.
2019-09-17 18:16:12 +03:00
emv
10555cebb1 0029711: General Fuse operation produces invalid result
Boolean Operations algorithm improvements:
1. To be able to add/remove elements into the tree of bounding boxes UBTree is replaced with EBTree in Boolean operations.
2. Perform repeated (nested) intersection of sub-shapes of the arguments with vertices which tolerances have been increased during the operation.
3. Edge/Edge and Edge/Face intersection point creation improvement for the cases when intersection point is located close to the edge's boundaries.
4. Forced Edge/Face intersection procedure to ensure common blocks creation.
5. Face/Face intersection post treatment stage improvements.
6. Avoid extension of the planar faces for Plane/Plane intersection.
7. Builder Face algorithm - improve classification of the potentially internal edges relatively new faces by adding filtering by bounding boxes.

Side effect changes:
1. IntTools_ShrunkRange is now keeps the length of the valid range of the edge.
2. The method BOPDS_DS::UpdateEdgeTolerance() has been removed as unused (replaced by the BOPAlgo_PaveFiller::UpdateEdgeTolerance()).

Test case for the issue 0029900.
Test case for the issue 0029711.
Adjustments of the existing test cases.
2019-09-03 11:44:49 +03:00
kgv
be74820241 0030915: Visualization - AIS_ColorScale::FindColor() returns Wrong color for maximal value
Map the very upper value (theValue==theMax) to the largest color interval.
2019-09-03 11:18:39 +03:00
msv
e6f0f25581 0030897: Modeling Algorithms - Crash in UnifySameDomain [Regression]
The regression caused by the patch for 0030534 has been eliminated. For that the method InsertWiresIntoFaces() has been corrected: the face to which a wire is added is first oriented as forward.
2019-09-03 11:05:53 +03:00
jgv
02fcb40f1c 0030534: Regression in the tool UnifySameDomain - the shape looses faces
1. Add method TransformPCurves to ShapeUpgrade_UnifySameDomain - to rotate and translate existing pcurves instead of projecting.
2. Modify method ShapeUpgrade_UnifySameDomain::IntUnifyFaces - now it does not apply ShapeFix to new wires and new faces.
3. In the method UnifyEdges: add merging degenerated edges.
2019-09-03 11:05:37 +03:00
jfa
e1c158598a 0030510: Application Framework - add missing NULL check within TDataStd_RealArray::ChangeArray() 2019-02-22 16:44:50 +03:00
vsr
1602aec50d Fix compilation problem
- Disable code introduced by fix for issue 28747, causing compilation failure
2019-02-21 13:37:34 +03:00
jgv
3aa2c1a020 0030363: BRepLib::SameParameter with option "forced" corrupts valid shape
Method BRepLib::SameParameter has been corrected to synchronize check of resulting tolerance with BRepCheck.
2019-02-20 11:47:59 +03:00
jgv
00a3bd0cb2 0030174: ShapeUpgrade_UnifySameDomain does not unify cylindrical faces
Hotfix for issue 27271 (avoiding potential seam edges) is deleted.

Correction of test case
2019-02-20 11:46:42 +03:00
jgv
9f4e2062c7 0030186: BRepOffsetAPI_MakePipe Generated() method produces no results for the spine edges
Add method BuildHistory providing history for sub-shapes of profile and spine to BRepFill_Pipe.
2019-02-20 11:36:20 +03:00
jgv
c3dd16e277 0030204: BRepOffsetAPI_MakePipeShell crash
Add protection from type mismatch while ensuring Same Parameter on U-edges
2019-02-20 11:36:02 +03:00
nbv
2a8846f92e 0030354: BOP Cut doesn't modify the attached face
The reason of this problem is in wrong work of classifier algorithm (see the message ~0080992 to the issue #30354). Therefore, the algorithm of IntTools_FClass2d class has been improved. Namely, now orientation of the polygon is computed from area-criterion instead of angle. As result, some simplification of the method IntTools_FClass2d::Init(...) has been made.

<!break>

1. New constructor has been added to the class CSLib_Class2d. It allows applying TColgp_SequenceOfPnt2d.

2. DRAW-commands "addpolygonnode" and "polygonprops" have been created. They are covered by the test case "tests/geometry/2dpolygon/A1".

3. New method Poly::PolygonProperties(...) has been created. See help for detailed information.

4. New testgrid "lowalgos classifier" has been created.
2018-11-15 12:49:09 +03:00
kgv
f082d3e3ae 0030143: Foundation Classes - provide operator[] alias for NCollection_Array1, NCollection_Vector 2018-11-15 12:48:58 +03:00
nbv
d3ee56eafc 0029807: [Regression to 7.0.0] Impossible to cut cone from prism
The algorithm has been improved for the cases when the intersection line goes through the cone apex.

<!break>

1. All special points are put to the ALine forcefully (if they are true intersection point). Currently this step has not been implemented yet.

2. Now the tolerance of IntPatch_Point (put into ALine) is computed in order to cover the distance between it and the correspond ALine.

3. Test cases have been created.

4. Procedure of trimming IntAna_Curve has been improved.

5. Criterion when the discriminant of IntAna_Curve can be considered to be equal to 0 has been improved.

6. Methods IntAna_Curve::FindParameter(...) (and IntPatch_ALine::FindParameter(...)) currently returns list of all parameters corresponding the given point (IntAna_Curve can be self-interfered curve). Before the fix, this method always returned only one (randomly chosen) parameter.

7. Interfaces of the following methods have been changed: IntAna_Curve::FindParameter(...), IntPatch_ALine::FindParameter(...), IntPatch_ALine::ChangeVertex(...), IntPatch_SpecialPoints::AddPointOnUorVIso(...), IntPatch_SpecialPoints::AddSingularPole(...), IntPatch_WLineTool::ExtendTwoWLines().

8. Following methods have been added: IntAna_Quadric::SpecialPoints(...), IntPatch_ALineToWLine::GetSectionRadius(...), IntPatch_SpecialPoints::ProcessSphere(...), IntPatch_SpecialPoints::ProcessCone(...), IntPatch_SpecialPoints::GetTangentToIntLineForCone(...).

------------------
1) tests/boolean/volumemaker/C5
   tests/boolean/volumemaker/C6
   tests/boolean/volumemaker/E7

They are real IMPROVEMENTS. In the FIX (in compare with MASTER), section result between pairs of faces f2&f6 (C5), f3&f7 (C6) and f1&f5 (E7) is closed. Separated test cases have been created in order to focus on the problem with section. Bug #28503 has been fixed.

Correction in test cases.
2018-09-24 14:38:17 +03:00
jgv
c66f6de371 0028949: BRepOffsetAPI_MakePipe Generated() method produces no result for spine edges
Add history for subshapes of spine: edges and vertices. Each edge of spine generates a shell. Each vertex of spine generates a set of edges and, possibly, faces (in the case of Round Corner).

(cherry picked from commit fcad97e74bdd3a96f0467188f5468b70cb0e2c81)
2018-09-21 18:04:50 +03:00
ifv
de3c005492 0029573: ConcatenateWireC0 crashes on two edges wire
Wrong setting first/last vertices is fixed
Test case added

(cherry picked from commit 73a7509fde)
2018-09-18 17:32:51 +03:00
nbv
2b58e5605a 0028085: Incorrect result of CUT operation
Before the fix, small arc of circle returned as intersection result. It was connected with the fact that the circle always was limited in 0 and 2*PI points. Currently the bounds of the circle (retrieved as an intersection curve) are computed from the real domain of the arguments (there is not a snap to the fixed 0 and 2*PI points).

(cherry picked from commit 94783b5111)
2018-09-18 17:31:36 +03:00
emv
f87605022c 0027928: BOP common produces empty compound
BOPTools_AlgoTools::ComputeState - increase the chance of correct classification of the face relatively solid by classifying the point located inside that face instead of the point taken near the edge of that face.
Test case for the issue.

(cherry picked from commit 56062e13f2)
2018-09-18 17:29:36 +03:00
249 changed files with 9471 additions and 3330 deletions

View File

@@ -82,6 +82,31 @@ namespace
Standard_Real aSaturation = NCollection_Lerp<Standard_Real>::Interpolate (theHlsMin[2], theHlsMax[2], aValue);
return Quantity_Color (AIS_ColorScale::hueToValidRange (aHue), aLightness, aSaturation, Quantity_TOC_HLS);
}
//! Return the index of discrete interval for specified value.
//! Note that when value lies exactly on the border between two intervals,
//! determining which interval to return is undefined operation;
//! Current implementation returns the following interval in this case.
//! @param theValue [in] value to map
//! @param theMin [in] values range, lower value
//! @param theMax [in] values range, upper value
//! @param theNbIntervals [in] number of discrete intervals
//! @return index of interval within [1, theNbIntervals] range
static Standard_Integer colorDiscreteInterval (Standard_Real theValue,
Standard_Real theMin,
Standard_Real theMax,
Standard_Integer theNbIntervals)
{
if (Abs (theMax - theMin) <= Precision::Approximation())
{
return 1;
}
Standard_Integer anInterval = 1 + (Standard_Integer )Floor (Standard_Real (theNbIntervals) * (theValue - theMin) / (theMax - theMin));
// map the very upper value (theValue==theMax) to the largest color interval
anInterval = Min (anInterval, theNbIntervals);
return anInterval;
}
}
//=======================================================================
@@ -347,21 +372,14 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
if (myColorType == Aspect_TOCSD_USER)
{
Standard_Integer anIndex = 0;
if (Abs (myMax - myMin) > Precision::Approximation())
{
anIndex = (theValue - myMin < Precision::Confusion())
? 1
: Standard_Integer (Ceiling (( theValue - myMin ) / ( (myMax - myMin) / myNbIntervals)));
}
if (anIndex <= 0 || anIndex > myColors.Length())
const Standard_Integer anInterval = colorDiscreteInterval (theValue, myMin, myMax, myNbIntervals);
if (anInterval < myColors.Lower() || anInterval > myColors.Upper())
{
theColor = Quantity_Color();
return Standard_False;
}
theColor = myColors.Value (anIndex);
theColor = myColors.Value (anInterval);
return Standard_True;
}
@@ -385,13 +403,8 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
return Standard_False;
}
Standard_Real anInterval = 0.0;
if (Abs (theMax - theMin) > Precision::Approximation())
{
anInterval = Floor (Standard_Real (theColorsCount) * (theValue - theMin) / (theMax - theMin));
}
theColor = colorFromValueEx (anInterval, 0, theColorsCount - 1, theColorHlsMin, theColorHlsMax);
const Standard_Integer anInterval = colorDiscreteInterval (theValue, theMin, theMax, theColorsCount);
theColor = colorFromValueEx (anInterval - 1, 0, theColorsCount - 1, theColorHlsMin, theColorHlsMax);
return Standard_True;
}

View File

@@ -32,6 +32,7 @@
#include <Prs3d_DatumAspect.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_PointAspect.hxx>
#include <Prs3d_Presentation.hxx>
#include <Prs3d_Projector.hxx>
#include <Prs3d_ShadingAspect.hxx>
@@ -60,6 +61,8 @@ AIS_Trihedron::AIS_Trihedron (const Handle(Geom_Axis2Placement)& theComponent)
myTrihDispMode (Prs3d_DM_WireFrame),
myComponent (theComponent)
{
myAutoHilight = Standard_False;
// selection priorities
mySelectionPriority.Bind (Prs3d_DP_None, 5); // complete triedron: priority 5 (same as faces)
mySelectionPriority.Bind (Prs3d_DP_Origin, 8); // origin: priority 8
@@ -71,6 +74,7 @@ AIS_Trihedron::AIS_Trihedron (const Handle(Geom_Axis2Placement)& theComponent)
{
mySelectionPriority.Bind ((Prs3d_DatumParts )aPartIter, 5); // planes: priority: 5
}
myHiddenLineAspect = new Graphic3d_AspectLine3d (Quantity_NOC_WHITE, Aspect_TOL_EMPTY, 1.0f);
// trihedron labels
myLabel.Bind (Prs3d_DP_XAxis, "X");
@@ -309,32 +313,35 @@ void AIS_Trihedron::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManag
aPresentation->Clear();
const Prs3d_DatumParts aPart = anOwner->DatumPart();
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPresentation);
Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
if (aPart >= Prs3d_DP_XOYAxis && aPart <= Prs3d_DP_XOZAxis)
{
// planes selection is equal in both shading and wireframe mode
aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (theStyle->LineAspect()->Aspect());
}
else
{
if (myTrihDispMode == Prs3d_DM_Shaded)
{
aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect(aPart)->Aspect());
aGroup->SetGroupPrimitivesAspect (theStyle->ShadingAspect()->Aspect());
}
else
{
if (aPart == Prs3d_DP_Origin)
{
aGroup->SetGroupPrimitivesAspect (getHighlightPointAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (theStyle->PointAspect()->Aspect());
}
else
{
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect(aPart)->Aspect());
aGroup->SetGroupPrimitivesAspect(theStyle->LineAspect()->Aspect());
}
}
}
aGroup->AddPrimitiveArray (arrayOfPrimitives(aPart));
const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN ? theStyle->ZLayer() : myDrawer->ZLayer();
if (aPresentation->GetZLayer() != aLayer)
aPresentation->SetZLayer (aLayer);
aPresentation->Highlight (theStyle);
thePM->AddToImmediateList (aPresentation);
}
@@ -351,25 +358,22 @@ void AIS_Trihedron::HilightSelected (const Handle(PrsMgr_PresentationManager3d)&
return;
}
Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
const Handle(Prs3d_Drawer)& aContextSelStyle = GetContext()->SelectionStyle();
const Quantity_Color& aSelectionColor = aContextSelStyle->Color();
Handle(Prs3d_Drawer) anAspect = !myHilightDrawer.IsNull() ? myHilightDrawer : GetContext()->SelectionStyle();
for (SelectMgr_SequenceOfOwner::Iterator anIterator (theOwners); anIterator.More(); anIterator.Next())
{
const Handle(SelectMgr_EntityOwner)& anOwner = anIterator.Value();
Handle(AIS_TrihedronOwner) aTrihedronOwner = Handle(AIS_TrihedronOwner)::DownCast(anOwner);
if (aTrihedronOwner.IsNull())
{
thePM->Color (this, aContextSelStyle, 0);
thePM->Color (this, anAspect, 0);
continue;
}
const Prs3d_DatumParts aPart = aTrihedronOwner->DatumPart();
Handle(Graphic3d_Group) aGroup;
if (mySelectedParts.Contains (aPart)
|| !myPartToGroup.Find (aPart, aGroup))
if (mySelectedParts.Contains (aPart) || !myPartToGroup.Find (aPart, aGroup))
{
continue;
}
@@ -377,27 +381,23 @@ void AIS_Trihedron::HilightSelected (const Handle(PrsMgr_PresentationManager3d)&
if (aPart >= Prs3d_DP_XOYAxis
&& aPart <= Prs3d_DP_XOZAxis)
{
getHighlightLineAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect()->Aspect());
}
else
{
if (isShadingMode)
{
getHighlightAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect()->Aspect());
}
else
{
if (aPart == Prs3d_DP_Origin)
{
getHighlightPointAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightPointAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
}
else
{
getHighlightLineAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect()->Aspect());
}
}
}
@@ -421,9 +421,9 @@ void AIS_Trihedron::ClearSelected()
if (aPart >= Prs3d_DP_XOYAxis
&& aPart <= Prs3d_DP_XOZAxis)
{
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
aGroup->SetGroupPrimitivesAspect (myHiddenLineAspect);
}
if (isShadingMode)
else if (isShadingMode)
{
aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
}
@@ -548,11 +548,8 @@ void AIS_Trihedron::computePresentation (const Handle(PrsMgr_PresentationManager
Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
myPartToGroup.Bind (aPart, aGroup);
const Handle(Graphic3d_AspectLine3d)& aLineAspect = anAspect->LineAspect (aPart)->Aspect();
aLineAspect->SetType (Aspect_TOL_EMPTY);
aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
aGroup->SetGroupPrimitivesAspect (aLineAspect);
aGroup->SetGroupPrimitivesAspect (myHiddenLineAspect);
}
}
@@ -941,65 +938,3 @@ void AIS_Trihedron::updatePrimitives(const Handle(Prs3d_DatumAspect)& theAspect,
myPrimitives.Bind(aPart, aPrims);
}
}
// =======================================================================
// function : getHighlightAspect
// purpose :
// =======================================================================
Handle(Prs3d_ShadingAspect) AIS_Trihedron::getHighlightAspect()
{
if (!myHighlightAspect.IsNull())
return myHighlightAspect;
Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
if (!myHilightDrawer.IsNull())
aHighlightColor = myHilightDrawer->Color();
myHighlightAspect = new Prs3d_ShadingAspect();
myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
myHighlightAspect->SetColor (aHighlightColor);
Graphic3d_MaterialAspect aHighlightMaterial;
aHighlightMaterial.SetColor (aHighlightColor);
myHighlightAspect->SetMaterial (aHighlightMaterial);
return myHighlightAspect;
}
// =======================================================================
// function : getHighlightLineAspect
// purpose :
// =======================================================================
Handle(Prs3d_LineAspect) AIS_Trihedron::getHighlightLineAspect()
{
if (!myHighlightLineAspect.IsNull())
return myHighlightLineAspect;
Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
if (!myHilightDrawer.IsNull())
aHighlightColor = myHilightDrawer->Color();
Handle(Prs3d_DatumAspect) aDatumAspect = Attributes()->DatumAspect();
Handle(Prs3d_LineAspect) aLineAspect = aDatumAspect->LineAspect(Prs3d_DP_XAxis);
myHighlightLineAspect = new Prs3d_LineAspect (aHighlightColor, aLineAspect->Aspect()->Type(),
aLineAspect->Aspect()->Width());
return myHighlightLineAspect;
}
// =======================================================================
// function : getHighlightPointAspect
// purpose :
// =======================================================================
Handle(Prs3d_PointAspect) AIS_Trihedron::getHighlightPointAspect()
{
if (!myHighlightPointAspect.IsNull())
return myHighlightPointAspect;
Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
if (!myHilightDrawer.IsNull())
aHighlightColor = myHilightDrawer->Color();
myHighlightPointAspect = new Prs3d_PointAspect (Aspect_TOM_PLUS, aHighlightColor, 1.0);
return myHighlightPointAspect;
}

View File

@@ -184,10 +184,16 @@ public:
return myLabel.Find (thePart);
}
public:
//! Returns highlight aspect , create if it is the first call
Standard_EXPORT Handle(Prs3d_ShadingAspect) getHighlightAspect();
//! Disables auto highlighting to use HilightSelected() and HilightOwnerWithColor() overridden methods.
virtual Standard_Boolean IsAutoHilight() const Standard_OVERRIDE { return false; }
//! Returns highlight line aspect , create if it is the first call
Standard_EXPORT Handle(Prs3d_LineAspect) getHighlightLineAspect();
//! Returns highlight point aspect , create if it is the first call
Standard_EXPORT Handle(Prs3d_PointAspect) getHighlightPointAspect();
public:
//! Method which clear all selected owners belonging
//! to this selectable object ( for fast presentation draw ).
@@ -250,13 +256,6 @@ protected:
const gp_Dir& theYDir,
const gp_Dir& theZDir);
//! Returns highlight line aspect , create if it is the first call
Handle(Prs3d_ShadingAspect) getHighlightAspect();
//! Returns highlight line aspect , create if it is the first call
Handle(Prs3d_LineAspect) getHighlightLineAspect();
//! Returns highlight line aspect , create if it is the first call
Handle(Prs3d_PointAspect) getHighlightPointAspect();
protected:
Standard_Boolean myHasOwnSize;
Standard_Boolean myHasOwnTextColor;
@@ -271,10 +270,7 @@ protected:
NCollection_DataMap<Prs3d_DatumParts, Handle(Graphic3d_Group)> myPartToGroup;
NCollection_List<Prs3d_DatumParts> mySelectedParts;
Handle(Prs3d_ShadingAspect) myHighlightAspect;
Handle(Prs3d_LineAspect) myHighlightLineAspect;
Handle(Prs3d_PointAspect) myHighlightPointAspect;
Handle(Graphic3d_AspectLine3d) myHiddenLineAspect;
NCollection_DataMap<Prs3d_DatumParts, Handle(Graphic3d_ArrayOfPrimitives)> myPrimitives;
};

View File

@@ -92,5 +92,8 @@ Error: The Feature Removal algorithm has failed
.BOPAlgo_AlertSolidBuilderUnusedFaces
Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
.BOPAlgo_AlertFaceBuilderUnusedEdges
Warning: Some of the edges passed to the Face Builder algorithm have not been classified and not used for faces creation
.BOPAlgo_AlertUnableToOrientTheShape
Warning: Unable to orient the shape correctly

View File

@@ -104,6 +104,10 @@ DEFINE_SIMPLE_ALERT(BOPAlgo_AlertRemoveFeaturesFailed)
//! and not used for solids creation
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces)
//! Some of the edges passed to the Face Builder algorithm have not been classified
//! and not used for faces creation
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertFaceBuilderUnusedEdges)
//! Unable to orient the shape correctly
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToOrientTheShape)

View File

@@ -95,5 +95,8 @@ static const char BOPAlgo_BOPAlgo_msg[] =
".BOPAlgo_AlertSolidBuilderUnusedFaces\n"
"Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n"
"\n"
".BOPAlgo_AlertFaceBuilderUnusedEdges\n"
"Warning: Some of the edges passed to the Face Builder algorithm have not been classified and not used for faces creation\n"
"\n"
".BOPAlgo_AlertUnableToOrientTheShape\n"
"Warning: Unable to orient the shape correctly\n";

View File

@@ -39,7 +39,7 @@
#include <IntTools_FClass2d.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_UBTreeFiller.hxx>
#include <TColStd_MapIntegerHasher.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
@@ -443,6 +443,7 @@ void BOPAlgo_BuilderFace::PerformAreas()
{
// No holes, stop the analysis
myAreas.Append(aNewFaces);
return;
}
// Classify holes relatively faces
@@ -580,76 +581,132 @@ void BOPAlgo_BuilderFace::PerformAreas()
//=======================================================================
void BOPAlgo_BuilderFace::PerformInternalShapes()
{
if (myAvoidInternalShapes) {
if (myAvoidInternalShapes)
// User-defined option to avoid internal edges
// in the result is in force.
return;
}
//
Standard_Integer aNbWI=myLoopsInternal.Extent();
if (!aNbWI) {// nothing to do
if (myLoopsInternal.IsEmpty())
// No edges left for classification
return;
// Prepare tree filler with the boxes of the edges to classify
NCollection_UBTree<Standard_Integer, Bnd_Box2d> aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
// Map of edges to classify
TopTools_IndexedMapOfShape anEdgesMap;
// Fill the tree and the map
TopTools_ListIteratorOfListOfShape itLE(myLoopsInternal);
for (; itLE.More(); itLE.Next())
{
TopoDS_Iterator itE(itLE.Value());
for (; itE.More(); itE.Next())
{
const TopoDS_Edge& aE = TopoDS::Edge(itE.Value());
if (!anEdgesMap.Contains(aE))
{
Bnd_Box2d aBoxE;
BRepTools::AddUVBounds(myFace, aE, aBoxE);
// Make sure the index of edge in the map and
// of the box in the tree is the same
aTreeFiller.Add(anEdgesMap.Add(aE), aBoxE);
}
}
}
//
//Standard_Real aTol;
Standard_Integer i;
BRep_Builder aBB;
TopTools_ListIteratorOfListOfShape aIt1, aIt2;
TopoDS_Iterator aIt;
TopTools_IndexedMapOfShape aME1, aME2, aMEP;
TopTools_IndexedDataMapOfShapeListOfShape aMVE;
// Shake the tree
aTreeFiller.Fill();
// Fence map
TColStd_MapOfInteger aMEDone;
// Classify edges relatively faces
TopTools_ListIteratorOfListOfShape itLF(myAreas);
for (; itLF.More(); itLF.Next())
{
TopoDS_Face& aF = *(TopoDS_Face*)&itLF.Value();
// Build box
Bnd_Box2d aBoxF;
BRepTools::AddUVBounds(aF, aBoxF);
// Select edges for the classification
BOPTools_BoxSelector<Bnd_Box2d> aSelector;
aSelector.SetBox(aBoxF);
if (!aBBTree.Select(aSelector))
continue;
// Collect edges inside the face
TopTools_IndexedMapOfShape anEdgesInside;
const TColStd_ListOfInteger& aLI = aSelector.Indices();
TColStd_ListIteratorOfListOfInteger itLI(aLI);
for (; itLI.More(); itLI.Next())
{
const Standard_Integer nE = itLI.Value();
if (aMEDone.Contains(nE))
continue;
const TopoDS_Edge& aE = TopoDS::Edge(anEdgesMap(nE));
if (IsInside(aE, aF, myContext))
{
anEdgesInside.Add(aE);
aMEDone.Add(nE);
}
}
if (anEdgesInside.IsEmpty())
continue;
// Make internal wires
TopTools_ListOfShape aLSI;
MakeInternalWires(anEdgesInside, aLSI);
// Add wires to a face
TopTools_ListIteratorOfListOfShape itLSI(aLSI);
for (; itLSI.More(); itLSI.Next())
{
const TopoDS_Shape& aWI = itLSI.Value();
BRep_Builder().Add(aF, aWI);
}
// Condition of early exit
if (aMEDone.Extent() == anEdgesMap.Extent())
// All edges are classified and added into the faces
return;
}
// Some edges are left unclassified - warn user about them
TopTools_IndexedMapOfShape anEdgesUnUsed;
for (Standard_Integer i = 1; i <= anEdgesMap.Extent(); ++i)
{
if (!aMEDone.Contains(i))
anEdgesUnUsed.Add(anEdgesMap(i));
}
// Make internal wires
TopTools_ListOfShape aLSI;
//
// 1. All internal edges
aIt1.Initialize(myLoopsInternal);
for (; aIt1.More(); aIt1.Next()) {
const TopoDS_Shape& aWire=aIt1.Value();
aIt.Initialize(aWire);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aE=aIt.Value();
aME1.Add(aE);
}
MakeInternalWires(anEdgesUnUsed, aLSI);
// Make compound
TopoDS_Compound aWShape;
BRep_Builder().MakeCompound(aWShape);
BRep_Builder().Add(aWShape, myFace);
if (aLSI.Extent() == 1)
BRep_Builder().Add(aWShape, aLSI.First());
else
{
TopoDS_Compound aCE;
BRep_Builder().MakeCompound(aCE);
for (TopTools_ListIteratorOfListOfShape it(aLSI); it.More(); it.Next())
BRep_Builder().Add(aCE, it.Value());
BRep_Builder().Add(aWShape, aCE);
}
//
// 2 Process faces
aIt2.Initialize(myAreas);
for ( ; aIt2.More(); aIt2.Next()) {
TopoDS_Face& aF=(*(TopoDS_Face *)(&aIt2.Value()));
//
aMVE.Clear();
TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
//
// 2.1 Separate faces to process aMEP
aME2.Clear();
aMEP.Clear();
aNbWI = aME1.Extent();
for (i = 1; i <= aNbWI; ++i) {
const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aME1(i)));
if (IsInside(aE, aF, myContext)) {
aMEP.Add(aE);
}
else {
aME2.Add(aE);
}
}
//
// 2.2 Make Internal Wires
aLSI.Clear();
MakeInternalWires(aMEP, aLSI);
//
// 2.3 Add them to aF
aIt1.Initialize(aLSI);
for (; aIt1.More(); aIt1.Next()) {
const TopoDS_Shape& aSI=aIt1.Value();
aBB.Add (aF, aSI);
}
//
// 2.4 Remove faces aMFP from aMF
aME1 = aME2;
//
aNbWI = aME1.Extent();
if (!aNbWI) {
break;
}
} //for ( ; aIt2.More(); aIt2.Next()) {
// Add warning
AddWarning(new BOPAlgo_AlertFaceBuilderUnusedEdges(aWShape));
}
//=======================================================================
//function : MakeInternalWires

View File

@@ -685,7 +685,8 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
aBB.Add(aWShape, aItLS.Value());
}
AddWarning(new BOPAlgo_AlertSolidBuilderUnusedFaces(aWShape)); }
AddWarning(new BOPAlgo_AlertSolidBuilderUnusedFaces(aWShape));
}
}
//=======================================================================
//function : MakeInternalShells

View File

@@ -461,6 +461,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
{
BOPAlgo_BuilderFace& aBF = aVBF(k);
aFacesIm.Add(myDS->Index(aBF.Face()), aBF.Areas());
myReport->Merge(aBF.GetReport());
}
aNbBF = aFacesIm.Extent();

View File

@@ -54,7 +54,10 @@ BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
(const Handle(NCollection_BaseAllocator)& theAllocator)
:
BOPAlgo_Algo(theAllocator)
BOPAlgo_Algo(theAllocator),
myFPBDone(1, theAllocator),
myIncreasedSS(1, theAllocator),
myVertsToAvoidExtension(1, theAllocator)
{
myDS = NULL;
myIterator = NULL;
@@ -134,6 +137,7 @@ void BOPAlgo_PaveFiller::Clear()
delete myDS;
myDS=NULL;
}
myIncreasedSS.Clear();
}
//=======================================================================
//function : DS
@@ -286,9 +290,17 @@ void BOPAlgo_PaveFiller::PerformInternal()
UpdatePaveBlocksWithSDVertices();
UpdateInterfsWithSDVertices();
// Repeat Intersection with increased vertices
RepeatIntersection();
if (HasErrors())
return;
// Force intersection of edges after increase
// of the tolerance values of their vertices
ForceInterfEE();
// Force Edge/Face intersection after increase
// of the tolerance values of their vertices
ForceInterfEF();
//
// 22
PerformFF();
@@ -326,3 +338,58 @@ void BOPAlgo_PaveFiller::PerformInternal()
return;
}
}
//=======================================================================
// function: RepeatIntersection
// purpose:
//=======================================================================
void BOPAlgo_PaveFiller::RepeatIntersection()
{
// Find all vertices with increased tolerance
TColStd_MapOfInteger anExtraInterfMap;
const Standard_Integer aNbS = myDS->NbSourceShapes();
for (Standard_Integer i = 0; i < aNbS; ++i)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() != TopAbs_VERTEX)
continue;
// Check if the tolerance of the original vertex has been increased
if (myIncreasedSS.Contains(i))
{
anExtraInterfMap.Add(i);
continue;
}
// Check if the vertex created a new vertex with greater tolerance
Standard_Integer nVSD;
if (!myDS->HasShapeSD(i, nVSD))
continue;
if (myIncreasedSS.Contains(nVSD))
anExtraInterfMap.Add(i);
}
if (anExtraInterfMap.IsEmpty())
return;
// Update iterator of pairs of shapes with interfering boxes
myIterator->PrepareExt(anExtraInterfMap);
// Perform intersections with vertices
PerformVV();
if (HasErrors())
return;
UpdatePaveBlocksWithSDVertices();
PerformVE();
if (HasErrors())
return;
UpdatePaveBlocksWithSDVertices();
PerformVF();
if (HasErrors())
return;
UpdatePaveBlocksWithSDVertices();
UpdateInterfsWithSDVertices();
}

View File

@@ -172,6 +172,14 @@ protected:
Bnd_Box,
TColStd_MapTransientHasher> BOPAlgo_DataMapOfPaveBlockBndBox;
typedef NCollection_DataMap
<Handle(BOPDS_PaveBlock),
TColStd_ListOfInteger,
TColStd_MapTransientHasher> BOPAlgo_DataMapOfPaveBlockListOfInteger;
typedef NCollection_DataMap
<Standard_Integer,
BOPDS_MapOfPaveBlock> BOPAlgo_DataMapOfIntegerMapOfPaveBlock;
//! Sets non-destructive mode automatically if an argument
//! contains a locked sub-shape (see TopoDS_Shape::Locked()).
@@ -265,7 +273,8 @@ protected:
TColStd_DataMapOfIntegerReal& theMVTol,
TColStd_DataMapOfIntegerListOfInteger& theDMVLV);
Standard_EXPORT void FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC);
Standard_EXPORT void FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC,
TColStd_DataMapOfIntegerReal& theMVTol);
//! Depending on the parameter aType it checks whether
//! the vertex nV was created in EE or EF intersections.
@@ -281,21 +290,30 @@ protected:
const TopoDS_Face& theF2,
BOPDS_Curve& theNC,
TColStd_ListOfInteger& theLBV);
//! Checks if the given pave block (created on section curve)
//! coincides with any of the pave blocks of the faces
//! created the section curve.
Standard_EXPORT Standard_Boolean IsExistingPaveBlock
(const Handle(BOPDS_PaveBlock)& thePB, const BOPDS_Curve& theNC,
const Standard_Real theTolR3D, const BOPDS_IndexedMapOfPaveBlock& theMPB,
const BOPDS_MapOfPaveBlock& theMPBCommon,
Handle(BOPDS_PaveBlock)& thePBOut, Standard_Real& theTolNew);
Standard_EXPORT Standard_Boolean IsExistingPaveBlock (const Handle(BOPDS_PaveBlock)& thePB, const BOPDS_Curve& theNC, const TColStd_ListOfInteger& theLSE);
//! Checks if the given pave block (created on section curve)
//! coincides with any of the edges shared between the faces
//! created the section curve.
Standard_EXPORT Standard_Boolean IsExistingPaveBlock(const Handle(BOPDS_PaveBlock)& thePB,
const BOPDS_Curve& theNC,
const TColStd_ListOfInteger& theLSE,
Standard_Integer& theNEOut,
Standard_Real& theTolNew);
//! Treatment of section edges.
Standard_EXPORT void PostTreatFF (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges,
TColStd_DataMapOfIntegerInteger& theDMNewSD,
const TopTools_IndexedMapOfShape& theMicroEdges,
const BOPDS_IndexedMapOfPaveBlock& theMicroPB,
const TopTools_IndexedMapOfShape& theVertsOnRejectedPB,
const Handle(NCollection_BaseAllocator)& theAllocator);
@@ -360,14 +378,24 @@ protected:
//! Adds the existing edges from the map <theMPBOnIn> which interfere
//! with the vertices from <theMVB> map to the post treatment of section edges.
Standard_EXPORT void ProcessExistingPaveBlocks (const Standard_Integer theInt, const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn, const TColStd_DataMapOfIntegerListOfInteger& theDMBV, BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB, TopTools_DataMapOfShapeInteger& theMVI, BOPDS_MapOfPaveBlock& theMPB);
Standard_EXPORT void ProcessExistingPaveBlocks (const Standard_Integer theInt,
const Standard_Integer nF1,
const Standard_Integer nF2,
const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
const TColStd_DataMapOfIntegerListOfInteger& theDMBV,
BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
TopTools_DataMapOfShapeInteger& theMVI,
BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap,
BOPDS_MapOfPaveBlock& theMPB);
//! Replaces existing pave block <thePB> with new pave blocks <theLPB>.
//! The list <theLPB> contains images of <thePB> which were created in
//! the post treatment of section edges.
Standard_EXPORT void UpdateExistingPaveBlocks (const Handle(BOPDS_PaveBlock)& thePB, BOPDS_ListOfPaveBlock& theLPB, const Standard_Integer nF1, const Standard_Integer nF2);
//! Tries to project the new edges on the faces contained in the <thePBFacesMap>.
Standard_EXPORT void UpdateExistingPaveBlocks(const Handle(BOPDS_PaveBlock)& thePB,
BOPDS_ListOfPaveBlock& theLPB,
const BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap);
//! Treatment of vertices that were created in EE intersections.
Standard_EXPORT void TreatNewVertices(const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, TopTools_IndexedDataMapOfShapeListOfShape& theImages);
@@ -382,8 +410,9 @@ protected:
Standard_EXPORT void PreparePostTreatFF (const Standard_Integer aInt, const Standard_Integer aCur, const Handle(BOPDS_PaveBlock)& aPB, BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB, TopTools_DataMapOfShapeInteger& aMVI, BOPDS_ListOfPaveBlock& aLPB);
//! Updates the information about faces
Standard_EXPORT void UpdateFaceInfo (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME, const TColStd_DataMapOfIntegerInteger& theDMV);
Standard_EXPORT void UpdateFaceInfo(BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
const TColStd_DataMapOfIntegerInteger& theDMV,
const BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap);
//! Updates tolerance of vertex with index <nV>
//! to make it interfere with edge.
@@ -485,17 +514,31 @@ protected:
//! Adds the warning about failed intersection of pair of sub-shapes
Standard_EXPORT void AddIntersectionFailedWarning(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2);
//! Repeat intersection of sub-shapes with increased vertices.
Standard_EXPORT void RepeatIntersection();
//! Updates vertices of CommonBlocks with real tolerance of CB.
Standard_EXPORT void UpdateVerticesOfCB();
//! The method looks for the additional common blocks among pairs of edges
//! which did not participate in edges intersection (PerformEE() method)
//! due to being rejected by bounding boxes intersection.
//! with the same bounding vertices.
Standard_EXPORT void ForceInterfEE();
//! The method looks for the additional edge/face common blocks
//! among pairs of edge/face having the same vertices.
Standard_EXPORT void ForceInterfEF();
//! Performs intersection of given pave blocks
//! with all faces from arguments.
Standard_EXPORT void ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
const Standard_Boolean theAddInterf);
//! When all section edges are created and no increase of the tolerance
//! of vertices put on the section edges is expected, make sure that
//! the created sections have valid range.
//! If any of the section edges do not have valid range, remove them
//! from Face/Face intersection info and from the input <theMSCPB> map.
//! Put such edges into <aMicroEdges> map for further unification of their
//! Put such edges into <MicroPB> map for further unification of their
//! vertices in the PostTreatFF method.
//!
//! All these section edges have already been checked to have valid range.
@@ -503,7 +546,7 @@ protected:
//! been put on other section edges with greater tolerance, which has caused
//! increase of the tolerance value of the vertices.
Standard_EXPORT void RemoveMicroSectionEdges(BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
TopTools_IndexedMapOfShape& theMicroEdges);
BOPDS_IndexedMapOfPaveBlock& theMicroPB);
TopTools_ListOfShape myArguments;
@@ -516,8 +559,12 @@ protected:
Standard_Boolean myAvoidBuildPCurve;
BOPAlgo_GlueEnum myGlue;
private:
BOPAlgo_DataMapOfIntegerMapOfPaveBlock myFPBDone; //!< Fence map of intersected faces and pave blocks
TColStd_MapOfInteger myIncreasedSS; //!< Sub-shapes with increased tolerance during the operation
TColStd_MapOfInteger myVertsToAvoidExtension; //!< Vertices located close to E/E or E/F intersection points
//! which has already been extended to cover the real intersection
//! points, and should not be extended any longer to be put
//! on a section curve.
};

View File

@@ -68,14 +68,27 @@ void BOPAlgo_PaveFiller::PerformVV()
for (; myIterator->More(); myIterator->Next()) {
myIterator->Value(n1, n2);
//
const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(n1)));
const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(n2)));
//
iFlag=BOPTools_AlgoTools::ComputeVV(aV1, aV2, myFuzzyValue);
if (myDS->HasInterf(n1, n2))
{
BOPAlgo_Tools::FillMap<Standard_Integer, TColStd_MapIntegerHasher>(n1, n2, aMILI, aAllocator);
continue;
}
// Check for SD vertices
Standard_Integer n1SD = n1;
myDS->HasShapeSD(n1, n1SD);
Standard_Integer n2SD = n2;
myDS->HasShapeSD(n2, n2SD);
const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(n1SD)));
const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(n2SD)));
iFlag = BOPTools_AlgoTools::ComputeVV(aV1, aV2, myFuzzyValue);
if (!iFlag) {
BOPAlgo_Tools::FillMap<Standard_Integer, TColStd_MapIntegerHasher>(n1, n2, aMILI, aAllocator);
}
}
}
//
// 2. Make blocks
BOPAlgo_Tools::MakeBlocks<Standard_Integer, TColStd_MapIntegerHasher>(aMILI, aMBlocks, aAllocator);
@@ -182,11 +195,12 @@ Standard_Integer BOPAlgo_PaveFiller::MakeSDVertices
}
//
if (theAddInterfs) {
myDS->AddInterf(n1, n2);
BOPDS_InterfVV& aVV = aVVs.Appended();
//
aVV.SetIndices(n1, n2);
aVV.SetIndexNew(nV);
if (myDS->AddInterf(n1, n2))
{
BOPDS_InterfVV& aVV = aVVs.Appended();
aVV.SetIndices(n1, n2);
aVV.SetIndexNew(nV);
}
}
}
}

View File

@@ -63,59 +63,40 @@ void BOPAlgo_PaveFiller::SetNonDestructive()
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::UpdateEdgeTolerance (const Standard_Integer nE,
const Standard_Real aTol)
const Standard_Real theTol)
{
Standard_Boolean bIsNewShape, bHasShapeSD;
Standard_Integer nV, nVx;
Standard_Real aTolV;
BRep_Builder aBB;
TColStd_ListIteratorOfListOfInteger aIt;
//
BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
const TColStd_ListOfInteger& aLI=aSIE.SubShapes();
//
if (myNonDestructive) {
bIsNewShape=myDS->IsNewShape(nE);
if (!bIsNewShape) {
BOPDS_ShapeInfo& aSIE = myDS->ChangeShapeInfo(nE);
const TColStd_ListOfInteger& aLI = aSIE.SubShapes();
// For the safe input mode avoid modifying the input shapes
if (myNonDestructive)
{
if (!myDS->IsNewShape(nE))
return;
}
//
aIt.Initialize(aLI);
for (; aIt.More(); aIt.Next()) {
nV = aIt.Value();
bHasShapeSD=myDS->HasShapeSD(nV, nVx);
if (bHasShapeSD) {
continue;
}
bIsNewShape=myDS->IsNewShape(nV);
if (!bIsNewShape) {
TColStd_ListIteratorOfListOfInteger itLI(aLI);
for (; itLI.More(); itLI.Next())
{
Standard_Integer nV = itLI.Value(), nVSD;
if (!myDS->IsNewShape(nV) &&
!myDS->HasShapeSD(nV, nVSD))
return;
}
}
}
//
// Update edge
const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
aBB.UpdateEdge(aE, aTol);
Bnd_Box& aBoxE=aSIE.ChangeBox();
BRep_Builder().UpdateEdge(aE, theTol);
Bnd_Box& aBoxE = aSIE.ChangeBox();
BRepBndLib::Add(aE, aBoxE);
aBoxE.SetGap(aBoxE.GetGap() + Precision::Confusion());
//
aIt.Initialize(aLI);
for (; aIt.More(); aIt.Next()) {
nV = aIt.Value();
bHasShapeSD=myDS->HasShapeSD(nV, nVx);
if (bHasShapeSD) {
nV=nVx;
}
const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
aTolV = BRep_Tool::Tolerance(aV);
if (aTolV < aTol) {
aBB.UpdateVertex(aV, aTol);
BOPDS_ShapeInfo& aSIV = myDS->ChangeShapeInfo(nV);
Bnd_Box& aBoxV = aSIV.ChangeBox();
BRepBndLib::Add(aV, aBoxV);
aBoxV.SetGap(aBoxV.GetGap() + Precision::Confusion());
}
// Update vertices
TColStd_ListIteratorOfListOfInteger itLI(aLI);
for (; itLI.More(); itLI.Next())
{
Standard_Integer nV = itLI.Value();
UpdateVertex(nV, theTol);
}
}
//=======================================================================
@@ -143,6 +124,7 @@ Standard_Integer BOPAlgo_PaveFiller::UpdateVertex
Bnd_Box& aBoxV = aSIV.ChangeBox();
BRepBndLib::Add(aVSD, aBoxV);
aBoxV.SetGap(aBoxV.GetGap() + Precision::Confusion());
myIncreasedSS.Add(nV);
}
return nVNew;
}
@@ -172,7 +154,13 @@ Standard_Integer BOPAlgo_PaveFiller::UpdateVertex
myDS->AddShapeSD(nV, nVNew);
//
myDS->InitPaveBlocksForVertex(nV);
//
// Add new vertex to map of vertices to avoid further extension
myVertsToAvoidExtension.Add(nVNew);
if (aTolV < aTolNew)
myIncreasedSS.Add(nV);
return nVNew;
}
//=======================================================================

View File

@@ -179,6 +179,10 @@ void BOPAlgo_PaveFiller::PerformVE()
continue;
}
//
if (myDS->HasInterf(nV, nE)) {
continue;
}
//
if (myDS->HasInterfShapeSubShapes(nV, nE)) {
continue;
}

View File

@@ -30,11 +30,13 @@
#include <BOPDS_PaveBlock.hxx>
#include <BOPDS_VectorOfInterfEE.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools2D.hxx>
#include <BOPTools_Parallel.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <gp_Pnt.hxx>
#include <IntTools_CommonPrt.hxx>
#include <IntTools_Context.hxx>
@@ -312,7 +314,7 @@ void BOPAlgo_PaveFiller::PerformEE()
continue;
}
//
Standard_Boolean bIsOnPave[4], bFlag;
Standard_Boolean bIsOnPave[4];
Standard_Integer nV[4], j;
Standard_Real aT1, aT2, aTol;
TopoDS_Vertex aVnew;
@@ -343,23 +345,50 @@ void BOPAlgo_PaveFiller::PerformEE()
continue;
}
//
bFlag = Standard_False;
for (j = 0; j < 4; ++j) {
if (bIsOnPave[j]) {
//add interf VE(nV[j], nE)
Standard_Boolean isVExists = Standard_False;
for (j = 0; j < 4; ++j)
{
if (bIsOnPave[j])
{
Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1;
bFlag = ForceInterfVE(nV[j], aPB, aMEdges);
break;
bIsOnPave[j] = ForceInterfVE(nV[j], aPB, aMEdges);
if (bIsOnPave[j]) isVExists = Standard_True;
}
}
if (bFlag) {
BOPDS_InterfEE& aEE = aEEs.Appended();
aEE.SetIndices(nE1, nE2);
aEE.SetCommonPart(aCPart);
continue;
}
//
BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
const gp_Pnt aPnew = BRep_Tool::Pnt(aVnew);
if (isVExists)
{
// The found intersection point is located closely to one of the
// pave blocks bounds. So, do not create the new vertex in this point.
// Check if this point is a real intersection point or just a touching point.
// If it is a touching point, do nothing.
// If it is an intersection point, update the existing vertex to cover the
// intersection point.
const gp_Pnt aPOnE1 = BRepAdaptor_Curve(aE1).Value(aT1);
const gp_Pnt aPOnE2 = BRepAdaptor_Curve(aE2).Value(aT2);
if (aPOnE1.Distance(aPOnE2) > Precision::Intersection())
// No intersection point
continue;
// Real intersection is present.
// Update the existing vertex to cover the intersection point.
for (j = 0; j < 4; ++j)
{
if (bIsOnPave[j])
{
const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[j]));
const gp_Pnt aP = BRep_Tool::Pnt(aV);
Standard_Real aDistPP = aP.Distance(aPnew);
// Just update the vertex
UpdateVertex(nV[j], aDistPP);
myVertsToAvoidExtension.Add(nV[j]);
}
}
}
Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
if (bAnalytical) {
// increase tolerance for Line/Line intersection, but do not update
@@ -375,7 +404,7 @@ void BOPAlgo_PaveFiller::PerformEE()
Standard_Integer nVS[2], iFound;
Standard_Real aTolVx, aD2, aDT2;
TColStd_MapOfInteger aMV;
gp_Pnt aPnew, aPx;
gp_Pnt aPx;
//
iFound=0;
j=-1;
@@ -391,8 +420,6 @@ void BOPAlgo_PaveFiller::PerformEE()
nVS[j]=nV[3];
}
//
aPnew=BRep_Tool::Pnt(aVnew);
//
for (Standard_Integer k1=0; k1<=j; ++k1) {
const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1]));
aTolVx=BRep_Tool::Tolerance(aVx);
@@ -459,7 +486,10 @@ void BOPAlgo_PaveFiller::PerformEE()
//=========================================
// post treatment
//=========================================
BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS);
BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS, myContext);
// Update vertices of common blocks with real CB tolerances
UpdateVerticesOfCB();
PerformNewVertices(aMVCPB, aAllocator);
//
if (aMEdges.Extent()) {
@@ -598,8 +628,11 @@ void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
thePB->Indices(nV1, nV2);
const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
// Original edge
// Get the edge
Standard_Integer nE = thePB->OriginalEdge();
if (nE < 0 && !thePB->HasEdge(nE))
return;
const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
// Range
Standard_Real aT1, aT2;
@@ -628,7 +661,7 @@ void BOPAlgo_PaveFiller::AnalyzeShrunkData(const Handle(BOPDS_PaveBlock)& thePB,
BRep_Tool::Range(theSR.Edge(), aEFirst, aELast);
thePB->Range(aPBFirst, aPBLast);
bWholeEdge = !(aPBFirst > aEFirst || aPBLast < aELast);
if (bWholeEdge) {
if (bWholeEdge && thePB->OriginalEdge() >= 0) {
aWarnShape = theSR.Edge();
}
else {
@@ -678,20 +711,20 @@ Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
//
const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
if (aSIE.HasSubShape(nV)) {
return Standard_False;
return Standard_True;
}
//
if (myDS->HasInterf(nV, nE)) {
return Standard_False;
return Standard_True;
}
//
if (myDS->HasInterfShapeSubShapes(nV, nE)) {
return Standard_False;
return Standard_True;
}
//
if (aPB->Pave1().Index() == nV ||
aPB->Pave2().Index() == nV) {
return Standard_False;
return Standard_True;
}
//
nVx = nV;
@@ -787,6 +820,41 @@ Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
return bValid;
}
//=======================================================================
//function : UpdateVerticesOfCB
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::UpdateVerticesOfCB()
{
// Fence map to avoid checking same Common block twice
BOPDS_MapOfPaveBlock aMPBFence;
BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
const Standard_Integer aNbPBP = aPBP.Length();
for (Standard_Integer i = 0; i < aNbPBP; ++i)
{
const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPB);
for (; itPB.More(); itPB.Next())
{
const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(itPB.Value());
if (aCB.IsNull())
continue;
const Handle(BOPDS_PaveBlock)& aPBR = aCB->PaveBlock1();
if (!aMPBFence.Add(aPBR))
continue;
Standard_Real aTolCB = aCB->Tolerance();
if (aTolCB > 0.)
{
UpdateVertex(aPBR->Pave1().Index(), aTolCB);
UpdateVertex(aPBR->Pave2().Index(), aTolCB);
}
}
}
}
//=======================================================================
//function : ForceInterfEE
//purpose :
@@ -794,28 +862,27 @@ Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
void BOPAlgo_PaveFiller::ForceInterfEE()
{
// Now that we have vertices increased and unified, try to find additional
// common blocks among the pairs of edges that did not participate in
// intersection (PerformEE() method) due to being rejected by bounding boxes.
// Here, we are interested in common blocks only, as all real intersections
// should have happened already. Thus, we need to look only for the same
// vertices in the pairs of pave blocks and check the coincidence of such pave blocks.
// common blocks among the pairs of edges.
// Since all real intersections should have already happened, here we
// are interested in common blocks only, thus we need to check only
// those pairs of pave blocks with the same bounding vertices.
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
// Initialize pave blocks for all SD vertices
// Initialize pave blocks for all vertices which participated in intersections
const Standard_Integer aNbS = myDS->NbSourceShapes();
for (Standard_Integer i = 0; i < aNbS; ++i)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() == TopAbs_VERTEX)
{
Standard_Integer nVSD;
if (myDS->HasShapeSD(i, nVSD))
if (myDS->HasInterf(i))
myDS->InitPaveBlocksForVertex(i);
}
}
// Find all Pave Blocks with both paves being SD vertices.
// Fill the connection map from bounding vertices to pave blocks
// having those bounding vertices
NCollection_IndexedDataMap<BOPDS_Pair,
BOPDS_ListOfPaveBlock,
BOPDS_PairMapHasher> aPBMap(1, anAlloc);
@@ -863,8 +930,7 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
if (!aNbPB)
return;
// Find pairs of Pave Blocks having the same SD vertices
// and put them into the vector for parallel intersection.
// Prepare pave blocks with the same vertices for intersection.
BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
for (Standard_Integer i = 1; i <= aNbPB; ++i)
@@ -892,9 +958,16 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB1.Value();
const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPB1);
const Standard_Integer nE1 = aPB1->OriginalEdge();
const Standard_Integer iR1 = myDS->Rank(nE1);
const TopoDS_Edge& aE1 = TopoDS::Edge(myDS->Shape(nE1));
Standard_Real aT11, aT12;
aPB1->Range(aT11, aT12);
BRepAdaptor_Curve aBAC1(aE1);
gp_Pnt aPm;
gp_Vec aVTgt1;
aBAC1.D1((aT11 + aT12) * 0.5, aPm, aVTgt1);
if (aVTgt1.SquareMagnitude() < gp::Resolution())
continue;
BOPDS_ListIteratorOfListOfPaveBlock aItLPB2 = aItLPB1;
for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next())
@@ -902,10 +975,18 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
const Handle(BOPDS_PaveBlock)& aPB2 = aItLPB2.Value();
const Handle(BOPDS_CommonBlock)& aCB2 = myDS->CommonBlock(aPB2);
const Standard_Integer nE2 = aPB2->OriginalEdge();
const Standard_Integer iR2 = myDS->Rank(nE2);
// Make sure that the edges came from different arguments
if (myDS->Rank(nE1) == myDS->Rank(nE2))
continue;
// Check that the edges came from different arguments
if (iR1 == iR2)
{
// If the sharing of the vertices is not original, but has been acquired
// during the operation, check the coincidence of the edges even if
// they came from the same argument
if (!myDS->IsNewShape(nV1) && (myDS->Rank(nV1) == iR1) ||
!myDS->IsNewShape(nV2) && (myDS->Rank(nV2) == iR2))
continue;
}
// Check that the Pave blocks do not form the Common block already
if (!aCB1.IsNull() && !aCB2.IsNull())
@@ -918,6 +999,28 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
Standard_Real aT21, aT22;
aPB2->Range(aT21, aT22);
// Check the angle between edges in the middle point.
// If the angle is more than 10 degrees, do not use the additional
// tolerance, as it may lead to undesired unification of edges
Standard_Boolean bUseAddTol = Standard_True;
{
GeomAPI_ProjectPointOnCurve& aProjPC = myContext->ProjPC(aE2);
aProjPC.Perform(aPm);
if (!aProjPC.NbPoints())
continue;
BRepAdaptor_Curve aBAC2(aE2);
gp_Pnt aPm2;
gp_Vec aVTgt2;
aBAC2.D1(aProjPC.LowerDistanceParameter(), aPm2, aVTgt2);
if (aVTgt2.SquareMagnitude() < gp::Resolution())
continue;
// The angle should be close to zero
Standard_Real aCos = aVTgt1.Dot(aVTgt2);
if (Abs(aCos) < 0.984)
bUseAddTol = Standard_False;
}
// Add pair for intersection
BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge.Appended();
anEdgeEdge.UseQuickCoincidenceCheck(Standard_True);
@@ -925,7 +1028,10 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
anEdgeEdge.SetPaveBlock2(aPB2);
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
if (bUseAddTol)
anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
else
anEdgeEdge.SetFuzzyValue(myFuzzyValue);
anEdgeEdge.SetProgressIndicator(myProgressIndicator);
}
}
@@ -975,6 +1081,16 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
const Standard_Integer nE1 = aPB[0]->OriginalEdge();
const Standard_Integer nE2 = aPB[1]->OriginalEdge();
if (myDS->Rank(nE1) == myDS->Rank(nE2))
{
// Add acquired self-interference warning
TopoDS_Compound aWC;
BRep_Builder().MakeCompound(aWC);
BRep_Builder().Add(aWC, myDS->Shape(nE1));
BRep_Builder().Add(aWC, myDS->Shape(nE2));
AddWarning(new BOPAlgo_AlertAcquiredSelfIntersection(aWC));
}
BOPDS_InterfEE& aEE = aEEs.Appended();
aEE.SetIndices(nE1, nE2);
aEE.SetCommonPart(aCP);

View File

@@ -184,6 +184,10 @@ void BOPAlgo_PaveFiller::PerformVF()
//
aVFs.SetIncrement(iSize);
//
// Avoid repeated intersection of the same vertex with face in case
// the group of vertices formed a single SD vertex
NCollection_DataMap<BOPDS_Pair, TColStd_MapOfInteger, BOPDS_PairMapHasher> aMVFPairs;
for (; myIterator->More(); myIterator->Next()) {
myIterator->Value(nV, nF);
//
@@ -191,6 +195,10 @@ void BOPAlgo_PaveFiller::PerformVF()
continue;
}
//
if (myDS->HasInterf(nV, nF)) {
continue;
}
//
myDS->ChangeFaceInfo(nF);
if (myDS->HasInterfShapeSubShapes(nV, nF)) {
continue;
@@ -201,12 +209,23 @@ void BOPAlgo_PaveFiller::PerformVF()
nVx=nVSD;
}
//
BOPDS_Pair aVFPair(nVx, nF);
TColStd_MapOfInteger* pMV = aMVFPairs.ChangeSeek(aVFPair);
if (pMV)
{
pMV->Add(nV);
continue;
}
pMV = aMVFPairs.Bound(aVFPair, TColStd_MapOfInteger());
pMV->Add(nV);
const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
//
BOPAlgo_VertexFace& aVertexFace=aVVF.Appended();
//
aVertexFace.SetIndices(nV, nF);
aVertexFace.SetIndices(nVx, nF);
aVertexFace.SetVertex(aV);
aVertexFace.SetFace(aF);
aVertexFace.SetFuzzyValue(myFuzzyValue);
@@ -231,22 +250,30 @@ void BOPAlgo_PaveFiller::PerformVF()
continue;
}
//
aVertexFace.Indices(nV, nF);
aVertexFace.Indices(nVx, nF);
aVertexFace.Parameters(aT1, aT2);
// 1
BOPDS_InterfVF& aVF=aVFs.Appended();
aVF.SetIndices(nV, nF);
aVF.SetUV(aT1, aT2);
// 2
myDS->AddInterf(nV, nF);
//
// 3 update vertex V/F if necessary
Standard_Real aTolVNew = aVertexFace.VertexNewTolerance();
nVx=UpdateVertex(nV, aTolVNew);
//
// 4
if (myDS->IsNewShape(nVx)) {
aVF.SetIndexNew(nVx);
BOPDS_Pair aVFPair(nVx, nF);
const TColStd_MapOfInteger& aMV = aMVFPairs.Find(aVFPair);
TColStd_MapIteratorOfMapOfInteger itMV(aMV);
for (; itMV.More(); itMV.Next())
{
nV = itMV.Value();
// 1
BOPDS_InterfVF& aVF = aVFs.Appended();
aVF.SetIndices(nV, nF);
aVF.SetUV(aT1, aT2);
// 2
myDS->AddInterf(nV, nF);
//
// 3 update vertex V/F if necessary
nVx = UpdateVertex(nV, aTolVNew);
//
// 4
if (myDS->IsNewShape(nVx)) {
aVF.SetIndexNew(nVx);
}
}
// 5 update FaceInfo
BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);

View File

@@ -30,10 +30,13 @@
#include <BOPDS_Pave.hxx>
#include <BOPDS_PaveBlock.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools2D.hxx>
#include <BOPTools_BoxSelector.hxx>
#include <BOPTools_Parallel.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <gp_Pnt.hxx>
#include <IntTools_CommonPrt.hxx>
#include <IntTools_Context.hxx>
@@ -41,6 +44,7 @@
#include <IntTools_Range.hxx>
#include <IntTools_SequenceOfCommonPrts.hxx>
#include <IntTools_Tools.hxx>
#include <NCollection_IncAllocator.hxx>
#include <NCollection_Vector.hxx>
#include <Precision.hxx>
#include <TColStd_MapOfInteger.hxx>
@@ -251,7 +255,11 @@ void BOPAlgo_PaveFiller::PerformEF()
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
aEdgeFace.SetRange (aPBRange);
aEdgeFace.SetProgressIndicator(myProgressIndicator);
//
// Save the pair to avoid their forced intersection
BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF);
if (!pMPB)
pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock());
pMPB->Add(aPB);
}//for (; aIt.More(); aIt.Next()) {
}//for (; myIterator->More(); myIterator->Next()) {
//
@@ -354,72 +362,86 @@ void BOPAlgo_PaveFiller::PerformEF()
continue;
}
//
for (j=0; j<2; ++j) {
if (bIsOnPave[j]) {
bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
if (bV[j]) {
const TopoDS_Vertex& aV=
(*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
//
Standard_Real f, l, aTolVnew, aDistPP, aTolPC, aTolV;
//
const Handle(Geom_Curve)& aCur = BRep_Tool::Curve(aE, f, l);
//
gp_Pnt aP1 = BRep_Tool::Pnt(aV);
gp_Pnt aP2 = aCur->Value(aT);
//
aDistPP=aP1.Distance(aP2);
//
aTolPC=Precision::PConfusion();
aTolV=BRep_Tool::Tolerance(aV);
if (aDistPP > (aTolV+aTolPC)) {
aTolVnew=Max(aTolE, aDistPP);
UpdateVertex(nV[j], aTolVnew);
}
}
else {
for (j = 0; j < 2; ++j)
{
if (bIsOnPave[j])
{
bV[j] = CheckFacePaves(nV[j], aMIFOn, aMIFIn);
if (!bV[j])
bIsOnPave[j] = ForceInterfVF(nV[j], nF);
}
}
if (bIsOnPave[0] || bIsOnPave[1])
{
// The found intersection point is located closely to one of the pave block's
// bounds. So, do not create the new vertex in this point.
// Check if this point is a real intersection, or just a touching point.
// If it is a touching point, do nothing.
// If it is an intersection point, update the existing vertex to cover the
// intersection point.
GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
const gp_Pnt aPnew = BRep_Tool::Pnt(aVnew);
aProjPS.Perform(aPnew);
Standard_Real aMinDistEF = (aProjPS.IsDone() && aProjPS.NbPoints()) ?
aProjPS.LowerDistance() : Precision::Infinite();
Standard_Boolean hasRealIntersection = aMinDistEF < Precision::Intersection();
if (!hasRealIntersection)
// no intersection point
continue;
// Real intersection is present.
// Update the existing vertex to cover the intersection point.
for (j = 0; j < 2; ++j)
{
if (bIsOnPave[j])
{
const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[j]));
const gp_Pnt aP = BRep_Tool::Pnt(aV);
Standard_Real aDistPP = aP.Distance(aPnew);
UpdateVertex(nV[j], aDistPP);
myVertsToAvoidExtension.Add(nV[j]);
}
}
continue;
}
if (CheckFacePaves(aVnew, aMIFOn)) {
continue;
}
//
if (!bIsOnPave[0] && !bIsOnPave[1]) {
if (CheckFacePaves(aVnew, aMIFOn)) {
continue;
}
//
Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
aTolVnew = Max(aTolVnew, Max(aTolE, aTolF));
BRep_Builder().UpdateVertex(aVnew, aTolVnew);
if (bLinePlane) {
// increase tolerance for Line/Plane intersection, but do not update
// the vertex till its intersection with some other shape
IntTools_Range aCR = aCPart.Range1();
aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.);
}
//
const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
//
if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) {
continue;
}
//
aMIEFC.Add(nF);
// 1
BOPDS_InterfEF& aEF=aEFs.Appended();
iX=aEFs.Length()-1;
aEF.SetIndices(nE, nF);
aEF.SetCommonPart(aCPart);
// 2
myDS->AddInterf(nE, nF);
// 3
BOPDS_CoupleOfPaveBlocks aCPB;
//
aCPB.SetPaveBlocks(aPB, aPB);
aCPB.SetIndexInterf(iX);
aCPB.SetTolerance(aTolVnew);
aMVCPB.Add(aVnew, aCPB);
Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
aTolVnew = Max(aTolVnew, Max(aTolE, aTolF));
BRep_Builder().UpdateVertex(aVnew, aTolVnew);
if (bLinePlane) {
// increase tolerance for Line/Plane intersection, but do not update
// the vertex till its intersection with some other shape
IntTools_Range aCR = aCPart.Range1();
aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.);
}
//
const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
//
if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) {
continue;
}
//
aMIEFC.Add(nF);
// 1
BOPDS_InterfEF& aEF = aEFs.Appended();
iX = aEFs.Length() - 1;
aEF.SetIndices(nE, nF);
aEF.SetCommonPart(aCPart);
// 2
myDS->AddInterf(nE, nF);
// 3
BOPDS_CoupleOfPaveBlocks aCPB;
//
aCPB.SetPaveBlocks(aPB, aPB);
aCPB.SetIndexInterf(iX);
aCPB.SetTolerance(aTolVnew);
aMVCPB.Add(aVnew, aCPB);
}
break;
case TopAbs_EDGE: {
@@ -453,7 +475,8 @@ void BOPAlgo_PaveFiller::PerformEF()
//=========================================
// post treatment
//=========================================
BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS, myContext);
UpdateVerticesOfCB();
PerformNewVertices(aMVCPB, aAllocator, Standard_False);
//
// Update FaceInfoIn for all faces having EF common parts
@@ -662,3 +685,343 @@ void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
}
}
}
//=======================================================================
//function : ForceInterfEF
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::ForceInterfEF()
{
if (!myIsPrimary)
return;
// Now that we have vertices increased and unified, try to find additional
// edge/face common blocks among the pairs of edge/face.
// Here, we are interested in common blocks only, as all real intersections
// should have happened already. Thus, we need to check only those pairs
// of edge/face which have the same vertices.
// Collect all pave blocks
BOPDS_IndexedMapOfPaveBlock aMPB;
const Standard_Integer aNbS = myDS->NbSourceShapes();
for (Standard_Integer nE = 0; nE < aNbS; ++nE)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE);
if (aSI.ShapeType() != TopAbs_EDGE)
// Not an edge
continue;
if (!aSI.HasReference())
// Edge has no pave blocks
continue;
if (aSI.HasFlag())
// Degenerated edge
continue;
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
for (; aItLPB.More(); aItLPB.Next())
{
const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
aMPB.Add(aPBR);
}
}
// Perform intersection of collected pave blocks with faces
ForceInterfEF(aMPB, Standard_True);
}
//=======================================================================
//function : ForceInterfEF
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
const Standard_Boolean theAddInterf)
{
if (theMPB.IsEmpty())
return;
// Fill the tree with bounding boxes of the pave blocks
NCollection_UBTree<Standard_Integer, Bnd_Box> aBBTree;
NCollection_UBTreeFiller<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc);
Standard_Integer aNbPB = theMPB.Extent();
for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
{
Handle(BOPDS_PaveBlock) aPB = theMPB(iPB);
if (!aPB->HasShrunkData() || !myDS->IsValidShrunkData(aPB))
{
FillShrunkData(aPB);
if (!aPB->HasShrunkData())
continue;
}
Standard_Real f, l;
Bnd_Box aPBBox;
Standard_Boolean isSplit;
aPB->ShrunkData(f, l, aPBBox, isSplit);
aTreeFiller.Add(aPBMap.Add(aPB), aPBBox);
}
// Shake the tree
aTreeFiller.Fill();
// Find pairs of Face/PaveBlock containing the same vertices
// and prepare those pairs for intersection.
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
const Standard_Integer aNbS = myDS->NbSourceShapes();
for (Standard_Integer nF = 0; nF < aNbS; ++nF)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
if (aSI.ShapeType() != TopAbs_FACE)
// Not a face
continue;
if (!aSI.HasReference())
// Face has no face info
continue;
const Bnd_Box& aBoxF = aSI.Box();
BOPTools_BoxSelector<Bnd_Box> aSelector;
aSelector.SetBox(aBoxF);
if (!aBBTree.Select(aSelector))
continue;
const TopoDS_Face& aF = TopoDS::Face(aSI.Shape());
const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF);
// Vertices of the face
TColStd_MapOfInteger aMVF;
const TColStd_MapOfInteger* pMVF[] = { &aFI.VerticesOn(),
&aFI.VerticesIn(),
&aFI.VerticesSc() };
for (Standard_Integer iM = 0; iM < 3; ++iM)
{
TColStd_MapIteratorOfMapOfInteger itM(*pMVF[iM]);
for (; itM.More(); itM.Next())
aMVF.Add(itM.Value());
}
// Pave Blocks of the face
const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(),
&aFI.PaveBlocksIn(),
&aFI.PaveBlocksSc() };
for (Standard_Integer iM = 0; iM < 3; ++iM)
{
const Standard_Integer aNb = pMPBF[iM]->Extent();
for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB)
{
const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB);
aMVF.Add(aPB->Pave1().Index());
aMVF.Add(aPB->Pave2().Index());
}
}
// Projection tool
GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
// Iterate on pave blocks and combine pairs containing
// the same vertices
const TColStd_ListOfInteger& aLIPB = aSelector.Indices();
TColStd_ListOfInteger::Iterator itLIPB(aLIPB);
for (; itLIPB.More(); itLIPB.Next())
{
const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value());
if (pMPBF[0]->Contains(aPB) ||
pMPBF[1]->Contains(aPB) ||
pMPBF[2]->Contains(aPB))
continue;
// Check if the face contains both vertices of the pave block
Standard_Integer nV1, nV2;
aPB->Indices(nV1, nV2);
if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2))
// Face does not contain the vertices
continue;
// Get the edge
Standard_Integer nE;
if (!aPB->HasEdge(nE))
{
nE = aPB->OriginalEdge();
if (nE < 0)
continue;
// Make sure that the edge and face came from different arguments
if (myDS->Rank(nF) == myDS->Rank(nE))
continue;
}
const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
BRepAdaptor_Curve aBAC(aE);
// Check directions coincidence at middle point on the edge
// and projection of that point on the face.
// If the angle between tangent vector to the curve and normal
// of the face is not in the range of 80 - 100 degrees, do not use the additional
// tolerance, as it may lead to undesired unification of edge with the face.
Standard_Boolean bUseAddTol = Standard_True;
Standard_Real aTS[2];
Bnd_Box aPBBox;
Standard_Boolean isSplit;
aPB->ShrunkData(aTS[0], aTS[1], aPBBox, isSplit);
// Middle point
gp_Pnt aPOnE;
// Tangent vector in the middle point
gp_Vec aVETgt;
aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt);
if (aVETgt.SquareMagnitude() < gp::Resolution())
continue;
aProjPS.Perform(aPOnE);
if (!aProjPS.NbPoints())
continue;
// Check the distance in the middle point, using the max vertices
// tolerance as the criteria.
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
Standard_Real aTolCheck = 2 * Max(BRep_Tool::Tolerance(aV1),
BRep_Tool::Tolerance(aV2));
if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
continue;
Standard_Real U, V;
aProjPS.LowerDistanceParameters(U, V);
if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V)))
continue;
gp_Pnt aPOnS = aProjPS.NearestPoint();
gp_Vec aVFNorm(aPOnS, aPOnE);
if (aVFNorm.SquareMagnitude() > gp::Resolution())
{
// Angle between vectors should be close to 90 degrees.
// We allow deviation of 10 degrees.
Standard_Real aCos = aVFNorm.Dot(aVETgt);
if (Abs(aCos) > 0.174)
bUseAddTol = Standard_False;
}
// Compute an addition to Fuzzy value
Standard_Real aTolAdd = 0.0;
if (bUseAddTol)
{
// Compute the distance from the bounding points of the edge
// to the face and use the maximal of these distances as a
// fuzzy tolerance for the intersection.
// Use the maximal tolerance of the pave block's vertices
// as a max criteria for the computed distance.
for (Standard_Integer iP = 0; iP < 2; ++iP)
{
gp_Pnt aP = aBAC.Value(aTS[iP]);
aProjPS.Perform(aP);
if (aProjPS.NbPoints())
{
Standard_Real aDistEF = aProjPS.LowerDistance();
if (aDistEF < aTolCheck && aDistEF > aTolAdd)
aTolAdd = aDistEF;
}
}
if (aTolAdd > 0.)
{
aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF));
if (aTolAdd < 0.)
aTolAdd = 0.;
}
}
Standard_Boolean bIntersect = aTolAdd > 0;
if (!bIntersect)
{
const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF);
bIntersect = !pMPB || !(pMPB->Contains(aPB));
}
if (bIntersect)
{
// Prepare pair for intersection
BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Appended();
aEdgeFace.SetIndices(nE, nF);
aEdgeFace.SetPaveBlock(aPB);
aEdgeFace.SetEdge(aE);
aEdgeFace.SetFace(aF);
aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
aEdgeFace.SetProgressIndicator(myProgressIndicator);
}
}
}
Standard_Integer aNbEFs = aVEdgeFace.Length();
if (!aNbEFs)
return;
aPBMap.Clear();
anAlloc->Reset();
// Perform intersection of the found pairs
BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
if (theAddInterf && aEFs.IsEmpty())
aEFs.SetIncrement(10);
// Analyze the results of intersection looking for TopAbs_EDGE
// intersection type only.
// Collect all pairs for common block creation
BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc);
for (Standard_Integer i = 0; i < aNbEFs; ++i)
{
BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i);
if (!anEdgeFace.IsDone() || anEdgeFace.HasErrors())
{
// Warn about failed intersection of sub-shapes
AddIntersectionFailedWarning(anEdgeFace.Edge(), anEdgeFace.Face());
continue;
}
const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts();
if (aCParts.Length() != 1)
continue;
const IntTools_CommonPrt& aCP = aCParts(1);
if (aCP.Type() != TopAbs_EDGE)
continue;
Standard_Integer nE, nF;
anEdgeFace.Indices(nE, nF);
if (theAddInterf)
{
// Add interference
BOPDS_InterfEF& aEF = aEFs.Appended();
aEF.SetIndices(nE, nF);
aEF.SetCommonPart(aCP);
myDS->AddInterf(nE, nF);
}
const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock();
// Update face information with new IN pave block
myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB);
if (theAddInterf)
// Fill map for common blocks creation
BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc);
}
if (aMPBLI.Extent())
// Create new common blocks for coinciding pairs
BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS);
}

File diff suppressed because it is too large Load Diff

View File

@@ -478,7 +478,7 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
aCB->SetEdge(nE);
// Compute tolerance of the common block and update the edge
Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
myDS->UpdateEdgeTolerance(nE, aTol);
UpdateEdgeTolerance(nE, aTol);
}
}
else if (aLPB.Extent() == 1)
@@ -527,10 +527,6 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext);
//======================================================
//
BOPDS_ShapeInfo aSI;
//
aSI.SetShapeType(TopAbs_EDGE);
//
for (k=0; k < aNbVBSE; ++k) {
BOPAlgo_SplitEdge& aBSE=aVBSE(k);
//
@@ -540,13 +536,18 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
//
BOPDS_ShapeInfo aSI;
aSI.SetShapeType(TopAbs_EDGE);
aSI.SetShape(aSp);
aSI.ChangeBox()=aBox;
TColStd_ListOfInteger& aSubShapes = aSI.ChangeSubShapes();
aSubShapes.Append(aPBk->Pave1().Index());
aSubShapes.Append(aPBk->Pave2().Index());
//
nSp=myDS->Append(aSI);
//
if (!aCBk.IsNull()) {
myDS->UpdateEdgeTolerance(nSp, aBSE.Tolerance());
UpdateEdgeTolerance(nSp, aBSE.Tolerance());
aCBk->SetEdge(nSp);
}
else {
@@ -644,54 +645,53 @@ void BOPAlgo_PaveFiller::MakePCurves()
continue;
}
//
Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
if (aCB.IsNull()) {
continue;
}
//
const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
if (aLPB.Extent()<2) {
continue;
}
//
BOPAlgo_MPC& aMPC=aVMPC.Appended();
//
aItLPB.Initialize(aLPB);
for(; aItLPB.More(); aItLPB.Next()) {
const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
if (aPBx==aPB) {
continue;
BOPAlgo_MPC& aMPC = aVMPC.Appended();
Handle(BOPDS_CommonBlock) aCB = myDS->CommonBlock(aPB);
if (!aCB.IsNull())
{
const BOPDS_ListOfPaveBlock& aLPB = aCB->PaveBlocks();
if (aLPB.Extent() >= 2)
{
aItLPB.Initialize(aLPB);
for(; aItLPB.More(); aItLPB.Next()) {
const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
if (aPBx==aPB) {
continue;
}
//
nEx=aPBx->OriginalEdge();
const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx)));
bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
if (!bHasPC) {
continue;
}
//
Standard_Integer nV1x, nV2x;
Standard_Real aT1x, aT2x;
TopoDS_Vertex aV1x, aV2x;
TopoDS_Edge aEz;
//
aEz=aEx;
aEz.Orientation(TopAbs_FORWARD);
//
aPBx->Indices(nV1x, nV2x);
aPBx->Range(aT1x, aT2x);
//
aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
aV1x.Orientation(TopAbs_FORWARD);
//
aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
aV2x.Orientation(TopAbs_REVERSED);
//
aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
//
break;
}
}
//
nEx=aPBx->OriginalEdge();
const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx)));
bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
if (!bHasPC) {
continue;
}
//
Standard_Integer nV1x, nV2x;
Standard_Real aT1x, aT2x;
TopoDS_Vertex aV1x, aV2x;
TopoDS_Edge aEz;
//
aEz=aEx;
aEz.Orientation(TopAbs_FORWARD);
//
aPBx->Indices(nV1x, nV2x);
aPBx->Range(aT1x, aT2x);
//
aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
aV1x.Orientation(TopAbs_FORWARD);
//
aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
aV2x.Orientation(TopAbs_REVERSED);
//
aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
//
break;
}
//
aMPC.SetEdge(aE);
aMPC.SetFace(aF1F);
aMPC.SetProgressIndicator(myProgressIndicator);

View File

@@ -112,7 +112,8 @@ void BOPAlgo_Tools::FillMap(const Handle(BOPDS_PaveBlock)& aPB,
//=======================================================================
void BOPAlgo_Tools::PerformCommonBlocks(BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& aMPBLPB,
const Handle(NCollection_BaseAllocator)& aAllocator,
BOPDS_PDS& pDS)
BOPDS_PDS& pDS,
const Handle(IntTools_Context)& theContext)
{
Standard_Integer aNbCB;
//
@@ -171,6 +172,10 @@ void BOPAlgo_Tools::PerformCommonBlocks(BOPDS_IndexedDataMapOfPaveBlockListOfPav
aCB->SetFaces(aLFaces);
for (aItLPB.Initialize(aLPB); aItLPB.More(); aItLPB.Next())
pDS->SetCommonBlock(aItLPB.Value(), aCB);
// Compute tolerance for Common Block
Standard_Real aTolCB = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, pDS, theContext);
aCB->SetTolerance(aTolCB);
}
}
//=======================================================================
@@ -179,7 +184,8 @@ void BOPAlgo_Tools::PerformCommonBlocks(BOPDS_IndexedDataMapOfPaveBlockListOfPav
//=======================================================================
void BOPAlgo_Tools::PerformCommonBlocks(const BOPDS_IndexedDataMapOfPaveBlockListOfInteger& aMPBLI,
const Handle(NCollection_BaseAllocator)& ,//aAllocator
BOPDS_PDS& pDS)
BOPDS_PDS& pDS,
const Handle(IntTools_Context)& theContext)
{
Standard_Integer nF, i, aNb;
TColStd_ListIteratorOfListOfInteger aItLI;
@@ -216,6 +222,9 @@ void BOPAlgo_Tools::PerformCommonBlocks(const BOPDS_IndexedDataMapOfPaveBlockLis
}
aCB->AppendFaces(aNewFaces);
pDS->SetCommonBlock(aPB, aCB);
// Compute tolerance for Common Block
Standard_Real aTolCB = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, pDS, theContext);
aCB->SetTolerance(aTolCB);
}
}
//=======================================================================
@@ -253,6 +262,10 @@ Standard_Real BOPAlgo_Tools::ComputeToleranceOfCB
aPBR->Range(aT1, aT2);
aDt = (aT2 - aT1) / (aNbPnt + 1);
//
Handle(IntTools_Context) aCtx = theContext;
if (aCtx.IsNull())
aCtx = new IntTools_Context();
// compute max tolerance for common blocks on edges
if (aLPB.Extent() > 1) {
// compute max distance between edges
@@ -270,7 +283,7 @@ Standard_Real BOPAlgo_Tools::ComputeToleranceOfCB
const TopoDS_Edge& aE = *(TopoDS_Edge*)&theDS->Shape(nE);
aTol = BRep_Tool::Tolerance(aE);
//
aProjPC = theContext->ProjPC(aE);
aProjPC = aCtx->ProjPC(aE);
//
aT = aT1;
for (Standard_Integer i=1; i <= aNbPnt; i++) {
@@ -299,7 +312,7 @@ Standard_Real BOPAlgo_Tools::ComputeToleranceOfCB
const TopoDS_Face& aF = *(TopoDS_Face*)&theDS->Shape(nF);
aTol = BRep_Tool::Tolerance(aF);
//
aProjPS = theContext->ProjPS(aF);
aProjPS = aCtx->ProjPS(aF);
//
aT = aT1;
for (Standard_Integer i=1; i <= aNbPnt; i++) {

View File

@@ -99,14 +99,19 @@ public:
const Standard_Integer theF,
BOPDS_IndexedDataMapOfPaveBlockListOfInteger& theMILI,
const Handle(NCollection_BaseAllocator)& theAllocator);
//! Create Common Blocks from the groups of pave blocks of <theMBlocks>
//! connection map.
Standard_EXPORT static void PerformCommonBlocks(BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& theMBlocks,
const Handle(NCollection_BaseAllocator)& theAllocator,
BOPDS_PDS& theDS);
BOPDS_PDS& theDS,
const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
//! Create Common Blocks on faces using the PB->Faces connection map <theMBlocks>.
Standard_EXPORT static void PerformCommonBlocks(const BOPDS_IndexedDataMapOfPaveBlockListOfInteger& theMBlocks,
const Handle(NCollection_BaseAllocator)& theAllocator,
BOPDS_PDS& pDS);
BOPDS_PDS& pDS,
const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
Standard_EXPORT static Standard_Real ComputeToleranceOfCB
(const Handle(BOPDS_CommonBlock)& theCB,

View File

@@ -23,7 +23,9 @@ IMPLEMENT_STANDARD_RTTIEXT(BOPDS_CommonBlock,Standard_Transient)
// function:
// purpose:
//=======================================================================
BOPDS_CommonBlock::BOPDS_CommonBlock()
BOPDS_CommonBlock::BOPDS_CommonBlock()
:
myTolerance(0.0)
{
}
//=======================================================================
@@ -33,7 +35,8 @@ IMPLEMENT_STANDARD_RTTIEXT(BOPDS_CommonBlock,Standard_Transient)
BOPDS_CommonBlock::BOPDS_CommonBlock(const Handle(NCollection_BaseAllocator)& theAllocator)
:
myPaveBlocks(theAllocator),
myFaces(theAllocator)
myFaces(theAllocator),
myTolerance(0.0)
{
}
//=======================================================================

View File

@@ -61,9 +61,7 @@ public:
//! Modifier
//! Adds the list of pave blocks <aLPB>
//! to the list of pave blocks
//! of the common block
//! Sets the list of pave blocks for the common block
Standard_EXPORT void SetPaveBlocks (const BOPDS_ListOfPaveBlock& aLPB);
@@ -154,13 +152,25 @@ public:
//! It will be representative for the whole group.
Standard_EXPORT void SetRealPaveBlock(const Handle(BOPDS_PaveBlock)& thePB);
//! Sets the tolerance for the common block
void SetTolerance(const Standard_Real theTol)
{
myTolerance = theTol;
}
//! Return the tolerance of common block
Standard_Real Tolerance() const
{
return myTolerance;
}
DEFINE_STANDARD_RTTIEXT(BOPDS_CommonBlock,Standard_Transient)
protected:
BOPDS_ListOfPaveBlock myPaveBlocks;
TColStd_ListOfInteger myFaces;
BOPDS_ListOfPaveBlock myPaveBlocks; //!< Pave blocks of the common block
TColStd_ListOfInteger myFaces; //!< Faces on which the pave blocks are lying
Standard_Real myTolerance; //!< Tolerance of the common block
private:

View File

@@ -88,7 +88,8 @@ BOPDS_DS::BOPDS_DS()
myInterfVZ(0, myAllocator),
myInterfEZ(0, myAllocator),
myInterfFZ(0, myAllocator),
myInterfZZ(0, myAllocator)
myInterfZZ(0, myAllocator),
myInterfered(100, myAllocator)
{
myNbShapes=0;
myNbSourceShapes=0;
@@ -119,7 +120,8 @@ BOPDS_DS::BOPDS_DS(const Handle(NCollection_BaseAllocator)& theAllocator)
myInterfVZ(0, myAllocator),
myInterfEZ(0, myAllocator),
myInterfFZ(0, myAllocator),
myInterfZZ(0, myAllocator)
myInterfZZ(0, myAllocator),
myInterfered(100, myAllocator)
{
myNbShapes=0;
myNbSourceShapes=0;
@@ -161,6 +163,7 @@ void BOPDS_DS::Clear()
myInterfEZ.Clear();
myInterfFZ.Clear();
myInterfZZ.Clear();
myInterfered.Clear();
}
//=======================================================================
//function : SetArguments
@@ -678,30 +681,6 @@ void BOPDS_DS::InitShape
}
}
//=======================================================================
//function : HasInterf
//purpose :
//=======================================================================
Standard_Boolean BOPDS_DS::HasInterf(const Standard_Integer theI) const
{
Standard_Integer n1, n2;
Standard_Boolean bRet;
BOPDS_MapIteratorOfMapOfPair aIt;
//
bRet = Standard_False;
//
aIt.Initialize(myInterfTB);
for (; aIt.More(); aIt.Next()) {
const BOPDS_Pair& aPK = aIt.Value();
aPK.Indices(n1, n2);
if (n1 == theI || n2 == theI) {
bRet = Standard_True;
break;
}
}
//
return bRet;
}
//=======================================================================
//function : HasInterfShapeSubShapes
//purpose :
@@ -1771,43 +1750,6 @@ void BOPDS_DS::Paves(const Standard_Integer theEdge,
}
}
//=======================================================================
// function: UpdateTolerance
// purpose:
//=======================================================================
void BOPDS_DS::UpdateEdgeTolerance(const Standard_Integer nE,
const Standard_Real aTol,
const Standard_Real theFuzz)
{
Standard_Integer nV;
Standard_Real aTolV;
BRep_Builder aBB;
TColStd_ListIteratorOfListOfInteger aIt;
//
Standard_Real aTolAdd = Max(theFuzz, Precision::Confusion()) * 0.5;
const TopoDS_Edge& aE = *(TopoDS_Edge*)&Shape(nE);
aBB.UpdateEdge(aE, aTol);
BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
Bnd_Box& aBoxE=aSIE.ChangeBox();
BRepBndLib::Add(aE, aBoxE);
aBoxE.SetGap(aBoxE.GetGap() + aTolAdd);
//
const TColStd_ListOfInteger& aLI = aSIE.SubShapes();
aIt.Initialize(aLI);
for (; aIt.More(); aIt.Next()) {
nV = aIt.Value();
const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&Shape(nV);
aTolV = BRep_Tool::Tolerance(aV);
if (aTolV < aTol) {
aBB.UpdateVertex(aV, aTol);
BOPDS_ShapeInfo& aSIV = ChangeShapeInfo(nV);
Bnd_Box& aBoxV = aSIV.ChangeBox();
BRepBndLib::Add(aV, aBoxV);
aBoxV.SetGap(aBoxV.GetGap() + aTolAdd);
}
}
}
//=======================================================================
//function : TotalShapes
//purpose :
//=======================================================================

View File

@@ -395,27 +395,23 @@ Standard_EXPORT virtual ~BOPDS_DS();
//! Returns the number of types of the interferences
static Standard_Integer NbInterfTypes();
static Standard_Integer NbInterfTypes();
//! Modifier
//! Adds the information about an interference between
//! shapes with indices theI1, theI2 to the summary
//! table of interferences
void AddInterf (const Standard_Integer theI1, const Standard_Integer theI2);
Standard_Boolean AddInterf (const Standard_Integer theI1, const Standard_Integer theI2);
//! Query
//! Returns true if the shape with index theI
//! is interferred
Standard_EXPORT Standard_Boolean HasInterf (const Standard_Integer theI) const;
Standard_Boolean HasInterf (const Standard_Integer theI) const;
//! Query
//! Returns true if the shapes with indices theI1, theI2
//! are interferred
Standard_Boolean HasInterf (const Standard_Integer theI1, const Standard_Integer theI2) const;
Standard_Boolean HasInterf (const Standard_Integer theI1, const Standard_Integer theI2) const;
//! Query
//! Returns true if the shape with index theI1 is interfered
@@ -444,12 +440,6 @@ Standard_EXPORT virtual ~BOPDS_DS();
//! Fills theLP with sorted paves
//! of the shape with index theIndex
Standard_EXPORT void Paves (const Standard_Integer theIndex, BOPDS_ListOfPave& theLP);
//! Updates tolerance of the sub-shapes of the shape with index <theIndex>.
Standard_EXPORT void UpdateEdgeTolerance (const Standard_Integer theIndex,
const Standard_Real theTolerance,
const Standard_Real theFuzz = Precision::Confusion());
//! Update the pave blocks for all shapes in data structure
Standard_EXPORT void UpdatePaveBlocksWithSDVertices();
@@ -518,6 +508,7 @@ protected:
BOPDS_VectorOfInterfEZ myInterfEZ;
BOPDS_VectorOfInterfFZ myInterfFZ;
BOPDS_VectorOfInterfZZ myInterfZZ;
TColStd_MapOfInteger myInterfered;
private:

View File

@@ -104,11 +104,24 @@ inline Standard_Integer BOPDS_DS::NbInterfTypes()
//function : AddInterf
//purpose :
//=======================================================================
inline void BOPDS_DS::AddInterf(const Standard_Integer theI1,
const Standard_Integer theI2)
inline Standard_Boolean BOPDS_DS::AddInterf(const Standard_Integer theI1,
const Standard_Integer theI2)
{
BOPDS_Pair aPK(theI1, theI2);
myInterfTB.Add(aPK);
if (myInterfTB.Add(BOPDS_Pair(theI1, theI2)))
{
myInterfered.Add(theI1);
myInterfered.Add(theI2);
return Standard_True;
}
return Standard_False;
}
//=======================================================================
//function : HasInterf
//purpose :
//=======================================================================
inline Standard_Boolean BOPDS_DS::HasInterf(const Standard_Integer theI) const
{
return myInterfered.Contains(theI);
}
//=======================================================================
//function : HasInterf

View File

@@ -42,8 +42,8 @@ class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{
BOPDS_TSR() :
BOPTools_BoxBndTreeSelector(),
myHasBRep(Standard_False),
myTree(NULL) {
}
myTree(NULL),
myIndex(-1) {}
//
virtual ~BOPDS_TSR() {
}
@@ -56,6 +56,10 @@ class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{
myTree=&aTree;
}
//
void SetIndex(const Standard_Integer theIndex) { myIndex = theIndex; }
//
Standard_Integer Index() const { return myIndex; }
//
void Perform() {
if (myHasBRep) {
myTree->Select(*this);
@@ -65,6 +69,7 @@ class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{
protected:
Standard_Boolean myHasBRep;
BOPTools_BoxBndTree *myTree;
Standard_Integer myIndex;
};
//
//=======================================================================
@@ -81,11 +86,12 @@ typedef BOPTools_Cnt <BOPDS_TSRFunctor, BOPDS_VectorOfTSR> BOPDS_TSRCnt;
BOPDS_Iterator::BOPDS_Iterator()
:
myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
myRunParallel(Standard_False)
myRunParallel(Standard_False),
myUseExt(Standard_False)
{
Standard_Integer i, aNb;
//
myDS=NULL;
myDS=NULL;
myLength=0;
//
aNb=BOPDS_DS::NbInterfTypes();
@@ -93,6 +99,12 @@ BOPDS_Iterator::BOPDS_Iterator()
for (i=0; i<aNb; ++i) {
myLists.Appended();
}
const Standard_Integer aNbExt = BOPDS_Iterator::NbExtInterfs();
myExtLists.SetIncrement(aNbExt);
for (i = 0; i < aNbExt; ++i) {
myExtLists.Appended();
}
}
//=======================================================================
//function :
@@ -103,7 +115,9 @@ BOPDS_Iterator::BOPDS_Iterator
:
myAllocator(theAllocator),
myLists(0, theAllocator),
myRunParallel(Standard_False)
myRunParallel(Standard_False),
myExtLists(0, theAllocator),
myUseExt(Standard_False)
{
Standard_Integer i, aNb;
//
@@ -115,6 +129,12 @@ BOPDS_Iterator::BOPDS_Iterator
for (i=0; i<aNb; ++i) {
myLists.Appended();
}
const Standard_Integer aNbExt = BOPDS_Iterator::NbExtInterfs();
myExtLists.SetIncrement(aNbExt);
for (i = 0; i < aNbExt; ++i) {
myExtLists.Appended();
}
}
//=======================================================================
//function : ~
@@ -192,12 +212,15 @@ void BOPDS_Iterator::Initialize(const TopAbs_ShapeEnum aType1,
//
myLength=0;
iX=BOPDS_Tools::TypeToInteger(aType1, aType2);
if (iX>=0) {
if (iX >= 0)
{
BOPDS_VectorOfPair& aPairs = (myUseExt && iX < BOPDS_Iterator::NbExtInterfs()) ?
myExtLists(iX) : myLists(iX);
// sort interfering pairs for constant order of intersection
std::stable_sort(myLists(iX).begin(), myLists(iX).end());
std::stable_sort(aPairs.begin(), aPairs.end());
// initialize iterator to access the pairs
myIterator.Init(myLists(iX));
myLength = myLists(iX).Length();
myIterator.Init(aPairs);
myLength = aPairs.Length();
}
}
//=======================================================================
@@ -272,8 +295,8 @@ void BOPDS_Iterator::Intersect(const Handle(IntTools_Context)& theCtx,
Standard_Integer iTi, iTj;
TopAbs_ShapeEnum aTi, aTj;
//
BOPTools_BoxBndTree aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
myBoxTree.Clear();
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(myBoxTree);
//
aNb = myDS->NbSourceShapes();
BOPDS_VectorOfTSR aVTSR(aNb);
@@ -290,8 +313,9 @@ void BOPDS_Iterator::Intersect(const Handle(IntTools_Context)& theCtx,
}
//
const Bnd_Box& aBoxEx=aSI.Box();
aTSR.SetTree(aBBTree);
aTSR.SetTree(myBoxTree);
aTSR.SetBox(aBoxEx);
aTSR.SetIndex(i);
//
aTreeFiller.Add(i, aBoxEx);
}
@@ -366,3 +390,115 @@ void BOPDS_Iterator::Intersect(const Handle(IntTools_Context)& theCtx,
aVTSR.Clear();
//-----------------------------------------------------scope_1 t
}
//=======================================================================
// function: PrepareExt
// purpose:
//=======================================================================
void BOPDS_Iterator::PrepareExt(const TColStd_MapOfInteger& theIndices)
{
if (!myDS)
return;
// Update UB tree of bounding boxes with the increased shapes.
// It is expected that not too many shapes will be modified during
// the intersection, so after updating the tree it should not become
// too unbalanced.
TColStd_MapIteratorOfMapOfInteger itM(theIndices);
for (; itM.More(); itM.Next())
{
Standard_Integer nV = itM.Value();
myBoxTree.Remove(nV);
// Add with new box
Standard_Integer nVSD = nV;
myDS->HasShapeSD(nV, nVSD);
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nVSD);
const Bnd_Box& aBox = aSI.Box();
myBoxTree.Add(nV, aBox);
}
// Clear the extra lists
const Standard_Integer aNbExt = BOPDS_Iterator::NbExtInterfs();
myLength = 0;
for (Standard_Integer i = 0; i < aNbExt; ++i)
myExtLists(i).Clear();
IntersectExt(theIndices);
myUseExt = Standard_True;
}
//=======================================================================
// function: IntersectExt
// purpose:
//=======================================================================
void BOPDS_Iterator::IntersectExt(const TColStd_MapOfInteger& theIndices)
{
// Prepare vector for parallel selection
BOPDS_VectorOfTSR aVTSR(theIndices.Extent());
TColStd_MapIteratorOfMapOfInteger itM(theIndices);
for (; itM.More(); itM.Next())
{
Standard_Integer nV = itM.Value();
Standard_Integer nVSD = nV;
myDS->HasShapeSD(nV, nVSD);
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nVSD);
const Bnd_Box& aBox = aSI.Box();
BOPDS_TSR& aTSR = aVTSR.Appended();
aTSR.SetHasBRep(Standard_True);
aTSR.SetTree(myBoxTree);
aTSR.SetBox(aBox);
aTSR.SetIndex(nV);
}
// Perform selection
BOPDS_TSRCnt::Perform(myRunParallel, aVTSR);
// Treat selections
// Fence map to avoid duplicating pairs
BOPDS_MapOfPair aMPFence;
const Standard_Integer aNb = aVTSR.Length();
for (Standard_Integer k = 0; k < aNb; ++k)
{
BOPDS_TSR& aTSRi = aVTSR(k);
const TColStd_ListOfInteger& aLI = aTSRi.Indices();
if (aLI.IsEmpty())
continue;
const Standard_Integer i = aTSRi.Index();
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
const Standard_Integer iRankI = myDS->Rank(i);
const TopAbs_ShapeEnum aTI = aSI.ShapeType();
const Standard_Integer iTI = BOPDS_Tools::TypeToInteger(aTI);
TColStd_ListIteratorOfListOfInteger itLI(aLI);
for (; itLI.More(); itLI.Next())
{
const Standard_Integer j = itLI.Value(); // Index in DS
const Standard_Integer iRankJ = myDS->Rank(j);
if (iRankI == iRankJ)
continue;
const BOPDS_ShapeInfo& aSJ = myDS->ShapeInfo(j);
const TopAbs_ShapeEnum aTJ = aSJ.ShapeType();
const Standard_Integer iTJ = BOPDS_Tools::TypeToInteger(aTJ);
// avoid interfering of the same shapes and shape with its sub-shapes
if (((iTI < iTJ) && aSI.HasSubShape(j)) ||
((iTI > iTJ) && aSJ.HasSubShape(i)))
continue;
BOPDS_Pair aPair(i, j);
if (aMPFence.Add(aPair))
{
const Standard_Integer iX = BOPDS_Tools::TypeToInteger(aTI, aTJ);
if (iX < BOPDS_Iterator::NbExtInterfs())
myExtLists(iX).Append(aPair);
}
}
}
}

View File

@@ -26,6 +26,7 @@
#include <BOPDS_PDS.hxx>
#include <BOPDS_VectorOfPair.hxx>
#include <BOPDS_VectorOfVectorOfPair.hxx>
#include <BOPTools_BoxBndTree.hxx>
#include <NCollection_BaseAllocator.hxx>
#include <Precision.hxx>
#include <Standard_Boolean.hxx>
@@ -33,12 +34,11 @@
class BOPDS_DS;
class IntTools_Context;
//! The class BOPDS_Iterator is
//! 1.to compute intersections between BRep sub-shapes
//! of arguments of an operation (see the class BOPDS_DS)
//! in terms of theirs bounding boxes
//! 2.provides interface to iterare the pairs of
//! 2.provides interface to iterate the pairs of
//! intersected sub-shapes of given type
class BOPDS_Iterator
{
@@ -86,6 +86,10 @@ public:
const Standard_Boolean theCheckOBB = Standard_False,
const Standard_Real theFuzzyValue = Precision::Confusion());
//! Updates the tree of Bounding Boxes with increased boxes and
//! intersects such elements with the tree.
Standard_EXPORT void PrepareExt(const TColStd_MapOfInteger& theIndicies);
//! Returns the number of intersections founded
Standard_EXPORT Standard_Integer ExpectedLength() const;
@@ -100,20 +104,40 @@ public:
//! Returns the flag of parallel processing
Standard_EXPORT Standard_Boolean RunParallel() const;
protected:
public: //! @name Number of extra interfering types
// Extra lists contain only V/V, V/E, V/F interfering pairs.
// Although E/E is also initialized (but never filled) for code simplicity.
static Standard_Integer NbExtInterfs() { return 4; }
protected: //! @name Protected methods for bounding boxes intersection
//! Intersects the Bounding boxes of sub-shapes of the arguments with the tree
//! and saves the interfering pairs for further geometrical intersection.
Standard_EXPORT virtual void Intersect(const Handle(IntTools_Context)& theCtx = Handle(IntTools_Context)(),
const Standard_Boolean theCheckOBB = Standard_False,
const Standard_Real theFuzzyValue = Precision::Confusion());
Handle(NCollection_BaseAllocator) myAllocator;
Standard_Integer myLength;
BOPDS_PDS myDS;
BOPDS_VectorOfVectorOfPair myLists;
BOPDS_VectorOfPair::Iterator myIterator;
Standard_Boolean myRunParallel;
//! Intersects the bounding boxes of the shapes with given indices in DS
//! with the tree of bounding boxes and saves the interfering pairs in
//! extra lists for further geometrical intersection.
Standard_EXPORT void IntersectExt(const TColStd_MapOfInteger& theIndices);
private:
protected: //! @name Fields
Handle(NCollection_BaseAllocator) myAllocator; //!< Allocator
Standard_Integer myLength; //!< Length of the intersection vector of
//! particular intersection type
BOPDS_PDS myDS; //!< Data Structure
BOPDS_VectorOfVectorOfPair myLists; //!< Pairs with interfering bounding boxes
BOPDS_VectorOfPair::Iterator myIterator; //!< Iterator on each interfering type
Standard_Boolean myRunParallel; //!< Flag for parallel processing
BOPTools_BoxBndTree myBoxTree; //!< Unbalanced tree of bounding boxes
BOPDS_VectorOfVectorOfPair myExtLists; //!< Extra pairs of sub-shapes found after
//! intersection of increased sub-shapes
Standard_Boolean myUseExt; //!< Information flag for using the extra lists
};

View File

@@ -128,7 +128,7 @@ void BOPTest::DebugCommands(Draw_Interpretor& theCommands)
__FILE__, bopindex, g);
theCommands.Add("bopsd", "Gets the Same domain shape. Use: bopsd #",
__FILE__, bopsd, g);
theCommands.Add("bopsc", "Shows the section curves. Use: bopsc [nF1 nF2]",
theCommands.Add("bopsc", "Shows the section curves. Use: bopsc [nF1 [nF2]]",
__FILE__, bopsc, g);
theCommands.Add("boppb", "Shows information about pave blocks. Use: boppb [#e]",
__FILE__, boppb, g);
@@ -637,8 +637,8 @@ Standard_Integer bopsc(Draw_Interpretor& di,
Standard_Integer n,
const char** a)
{
if (n != 1 && n != 3) {
di << "Shows the section curves. Use: bopsc [nF1 nF2]\n";
if (n > 3) {
di.PrintHelp(a[0]);
return 1;
}
//
@@ -658,11 +658,11 @@ Standard_Integer bopsc(Draw_Interpretor& di,
BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
//
nSF1 = nSF2 = -1;
if (n == 3) {
if (n > 1)
nSF1 = Draw::Atoi(a[1]);
if (n > 2)
nSF2 = Draw::Atoi(a[2]);
}
//
BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
//
iCnt = 0;
@@ -676,6 +676,10 @@ Standard_Integer bopsc(Draw_Interpretor& di,
}
iPriz = 1;
}
else if (n == 2) {
if (!aFF.Contains(nSF1))
continue;
}
//
aFF.Indices(nF1, nF2);
//

View File

@@ -617,46 +617,50 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
(const TopoDS_Face& theF,
const TopoDS_Solid& theRef,
const Standard_Real theTol,
TopTools_IndexedMapOfShape& theBounds,
const TopTools_IndexedMapOfShape& theBounds,
const Handle(IntTools_Context)& theContext)
{
TopAbs_State aState;
TopExp_Explorer aExp;
TopoDS_Edge aE1;
gp_Pnt2d aP2D;
gp_Pnt aP3D;
//
aState=TopAbs_UNKNOWN;
//
aExp.Init(theF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
if (BRep_Tool::Degenerated(aSE)) {
TopAbs_State aState = TopAbs_UNKNOWN;
// Try to find the edge on the face which does not
// belong to the solid and classify the middle point of that
// edge relatively solid.
TopExp_Explorer aExp(theF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next())
{
const TopoDS_Edge& aSE = (*(TopoDS_Edge*)(&aExp.Current()));
if (BRep_Tool::Degenerated(aSE))
continue;
}
//
if (!theBounds.Contains(aSE)) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol,
theContext);
if (!theBounds.Contains(aSE))
{
aState = BOPTools_AlgoTools::ComputeState(aSE, theRef, theTol, theContext);
return aState;
}
if (aE1.IsNull()) {
aE1=(*(TopoDS_Edge*)(&aSE));
}
}
// !!<- process edges that are all on theRef
if (!aE1.IsNull()) {
const Standard_Integer anErrID = BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
aP2D, aP3D,
theContext);
if(anErrID == 0)
// All edges of the face are on the solid.
// Get point inside the face and classify it relatively solid.
gp_Pnt aP3D;
gp_Pnt2d aP2D;
Standard_Integer iErr = BOPTools_AlgoTools3D::PointInFace(theF, aP3D, aP2D, theContext);
if (iErr != 0)
{
// Hatcher fails to find the point -> get point near some edge
aExp.Init(theF, TopAbs_EDGE);
for (; aExp.More() && iErr != 0; aExp.Next())
{
aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
theContext);
const TopoDS_Edge& aSE = TopoDS::Edge(aExp.Current());
if (BRep_Tool::Degenerated(aSE))
continue;
iErr = BOPTools_AlgoTools3D::PointNearEdge(aSE, theF, aP2D, aP3D, theContext);
}
}
//
if (iErr == 0)
aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
return aState;
}
//=======================================================================
@@ -760,7 +764,6 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace
const Handle(IntTools_Context)& theContext)
{
Standard_Boolean bDegenerated;
Standard_Integer aNbF, iRet, iFound;
TopAbs_Orientation aOr;
TopoDS_Edge aE1;
TopExp_Explorer aExp;
@@ -771,14 +774,8 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace
// iRet=0; - state is not IN
// iRet=1; - state is IN
// iRet=2; - state can not be found by the method of angles
//
// For this function the returned value iRet means:
// iRet=0; - state is not IN
// iRet=1; - state is IN
//
iRet=0;
Standard_Integer iRet = 0;
// 1 Try to find an edge from theFace in theMEF
iFound=0;
aExp.Init(theFace, TopAbs_EDGE);
for(; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
@@ -786,8 +783,6 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace
continue;
}
//
++iFound;
//
aOr=aE.Orientation();
if (aOr==TopAbs_INTERNAL) {
continue;
@@ -798,18 +793,13 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace
}
// aE
TopTools_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
aNbF=aLF.Extent();
if (!aNbF) {
return iRet != 0; // it can not be so
}
//
else if (aNbF==1) {
Standard_Integer aNbF = aLF.Extent();
if (aNbF==1) {
// aE is internal edge on aLF.First()
const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
if (aE1.Orientation()!=TopAbs_INTERNAL) {
iRet=2;
break;
if (aE1.Orientation() != TopAbs_INTERNAL) {
continue;
}
//
iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1,
@@ -820,31 +810,14 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace
else if (aNbF==2) {
const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
//
if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
// treat as it was for 1 face
iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
theContext);
break;
}
}
//
if (aNbF%2) {
return Standard_False; // it can not be so
}
else { // aNbF=2,4,6,8,...
iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF,
iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
theContext);
break;
}
}//for(; aExp.More(); aExp.Next()) {
//
if (!iFound) {
// the face has no shared edges with the solid
iRet=2;
}
//
if (iRet!=2) {
if (aExp.More() && iRet != 2)
{
return iRet == 1;
}
//

View File

@@ -202,13 +202,13 @@ public: //! @name Point/Edge/Face classification relatively solid
//! Computes the 3-D state of the face theFace
//! toward solid theSolid.
//! theTol - value of precision of computation
//! theBounds - set of edges of theFace to avoid
//! theBounds - set of edges of <theSolid> to avoid
//! theContext- cahed geometrical tools
//! Returns 3-D state.
Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Face& theFace,
const TopoDS_Solid& theSolid,
const Standard_Real theTol,
TopTools_IndexedMapOfShape& theBounds,
const TopTools_IndexedMapOfShape& theBounds,
const Handle(IntTools_Context)& theContext);
//! Computes the 3-D state of the shape theShape

View File

@@ -58,9 +58,9 @@ static
//purpose :
//=======================================================================
Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
(const TopoDS_Edge& aE2, // old
const TopoDS_Edge& aE1, // new
const TopoDS_Face& aF,
(const TopoDS_Edge& theE2, // old
const TopoDS_Edge& theE1, // new
const TopoDS_Face& theF,
const Handle(IntTools_Context)& aCtx)
{
Standard_Boolean bIsToReverse, bIsClosed, bComp;
@@ -73,6 +73,13 @@ Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
//
iRet=0;
//
TopoDS_Face aF = theF;
aF.Orientation (TopAbs_FORWARD);
TopoDS_Edge aE1 = theE1;
aE1.Orientation (TopAbs_FORWARD);
TopoDS_Edge aE2 = theE2;
aE2.Orientation (TopAbs_FORWARD);
//
aC2Dold=BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
if (aC2Dold.IsNull()){
iRet=1;

View File

@@ -17,10 +17,10 @@
#include <Bnd_Box.hxx>
#include <BOPTools_BoxSelector.hxx>
#include <NCollection_UBTree.hxx>
#include <NCollection_EBTree.hxx>
#include <Standard_Integer.hxx>
typedef NCollection_UBTree<Standard_Integer, Bnd_Box> BOPTools_BoxBndTree;
typedef NCollection_EBTree<Standard_Integer, Bnd_Box> BOPTools_BoxBndTree;
typedef BOPTools_BoxSelector<Bnd_Box> BOPTools_BoxBndTreeSelector;
#endif
#endif

View File

@@ -421,9 +421,9 @@ TopoDS_Edge BRepAlgo::ConcatenateWireC0(const TopoDS_Wire& aWire)
isReverse = !IsFwdSeq(1);
}
TopoDS_Vertex FirstVtx_final = (isReverse)? LastVertex : FirstVertex;
TopoDS_Vertex FirstVtx_final = FirstVertex;
FirstVtx_final.Orientation(TopAbs_FORWARD);
TopoDS_Vertex LastVtx_final = (isReverse)? FirstVertex : LastVertex;
TopoDS_Vertex LastVtx_final = LastVertex;
LastVtx_final.Orientation(TopAbs_REVERSED);
if (CurveSeq.IsEmpty())

View File

@@ -24,6 +24,11 @@
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Wire.hxx>
#include <Adaptor3d_Curve.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <GeomAbs_CurveType.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <gp_Elips.hxx>
//=======================================================================
//function : Add
@@ -45,6 +50,7 @@ void BRepCheck::Add(BRepCheck_ListOfStatus& lst, const BRepCheck_Status stat)
}
lst.Append(stat);
}
//=======================================================================
//function : SelfIntersection
//purpose :
@@ -58,6 +64,67 @@ Standard_Boolean BRepCheck::SelfIntersection(const TopoDS_Wire& W,
BRepCheck_Status stat = chkw->SelfIntersect(myFace,RetE1,RetE2);
return (stat == BRepCheck_SelfIntersectingWire);
}
//=======================================================================
//function : PrecCurve
//purpose :
//=======================================================================
Standard_Real BRepCheck::PrecCurve(const Adaptor3d_Curve& aAC3D)
{
Standard_Real aXEmax = RealEpsilon();
//
GeomAbs_CurveType aCT = aAC3D.GetType();
if (aCT==GeomAbs_Ellipse) {
Standard_Real aX[5];
//
gp_Elips aEL3D=aAC3D.Ellipse();
aEL3D.Location().Coord(aX[0], aX[1], aX[2]);
aX[3]=aEL3D.MajorRadius();
aX[4]=aEL3D.MinorRadius();
aXEmax=-1.;
for (Standard_Integer i = 0; i < 5; ++i) {
if (aX[i]<0.) {
aX[i]=-aX[i];
}
Standard_Real aXE = Epsilon(aX[i]);
if (aXE > aXEmax) {
aXEmax = aXE;
}
}
}//if (aCT=GeomAbs_Ellipse) {
//
return aXEmax;
}
//=======================================================================
//function : PrecSurface
//purpose :
//=======================================================================
Standard_Real BRepCheck::PrecSurface(const Handle(Adaptor3d_HSurface)& aAHSurf)
{
Standard_Real aXEmax = RealEpsilon();
//
GeomAbs_SurfaceType aST = aAHSurf->GetType();
if (aST == GeomAbs_Cone) {
gp_Cone aCone=aAHSurf->Cone();
Standard_Real aX[4];
//
aCone.Location().Coord(aX[0], aX[1], aX[2]);
aX[3]=aCone.RefRadius();
aXEmax=-1.;
for (Standard_Integer i = 0; i < 4; ++i) {
if (aX[i] < 0.) {
aX[i] = -aX[i];
}
Standard_Real aXE = Epsilon(aX[i]);
if (aXE > aXEmax) {
aXEmax = aXE;
}
}
}//if (aST==GeomAbs_Cone) {
return aXEmax;
}
//=======================================================================
//function : Print
//purpose :

View File

@@ -28,6 +28,8 @@
class TopoDS_Wire;
class TopoDS_Face;
class TopoDS_Edge;
class Adaptor3d_Curve;
class Adaptor3d_HSurface;
class BRepCheck_Result;
class BRepCheck_Vertex;
class BRepCheck_Edge;
@@ -53,6 +55,11 @@ public:
Standard_EXPORT static Standard_Boolean SelfIntersection (const TopoDS_Wire& W, const TopoDS_Face& F, TopoDS_Edge& E1, TopoDS_Edge& E2);
//! Returns the resolution on the 3d curve
Standard_EXPORT static Standard_Real PrecCurve(const Adaptor3d_Curve& aAC3D);
//! Returns the resolution on the surface
Standard_EXPORT static Standard_Real PrecSurface(const Handle(Adaptor3d_HSurface)& aAHSurf);

View File

@@ -77,10 +77,6 @@ static
static
Standard_Real Prec(const Adaptor3d_Curve& aAC3D,
const Adaptor3d_CurveOnSurface& aACS);
static
Standard_Real PrecCurve(const Adaptor3d_Curve& aAC3D);
static
Standard_Real PrecSurface(const Adaptor3d_CurveOnSurface& aACS);
//static Standard_Boolean Validate(const Adaptor3d_Curve&,
// const Adaptor3d_Curve&,
@@ -898,87 +894,23 @@ Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
return Status ;
}
//=======================================================================
//function : Prec
//purpose :
//=======================================================================
Standard_Real Prec(const Adaptor3d_Curve& aAC3D,
const Adaptor3d_CurveOnSurface& aACS)
const Adaptor3d_CurveOnSurface& aACS)
{
Standard_Real aXEmax, aXC, aXS;
const Handle(Adaptor3d_HSurface)& aAHS = aACS.GetSurface();
//
aXC=PrecCurve(aAC3D);
aXS=PrecSurface(aACS);
aXEmax=(aXC>aXS) ? aXC: aXS;
return aXEmax;
}
//=======================================================================
//function : PrecCurve
//purpose :
//=======================================================================
Standard_Real PrecCurve(const Adaptor3d_Curve& aAC3D)
{
Standard_Real aXEmax;
GeomAbs_CurveType aCT;
//
aXEmax=RealEpsilon();
//
aCT=aAC3D.GetType();
if (aCT==GeomAbs_Ellipse) {
Standard_Integer i;
Standard_Real aX[5], aXE;
//
gp_Elips aEL3D=aAC3D.Ellipse();
aEL3D.Location().Coord(aX[0], aX[1], aX[2]);
aX[3]=aEL3D.MajorRadius();
aX[4]=aEL3D.MinorRadius();
aXEmax=-1.;
for (i=0; i<5; ++i) {
if (aX[i]<0.) {
aX[i]=-aX[i];
}
aXE=Epsilon(aX[i]);
if (aXE>aXEmax) {
aXEmax=aXE;
}
}
}//if (aCT=GeomAbs_Ellipse) {
//
return aXEmax;
}
//=======================================================================
//function : PrecSurface
//purpose :
//=======================================================================
Standard_Real PrecSurface(const Adaptor3d_CurveOnSurface& aACS)
{
Standard_Real aXEmax;
GeomAbs_SurfaceType aST;
//
aXEmax=RealEpsilon();
//
const Handle(Adaptor3d_HSurface)& aAHS=aACS.GetSurface();
aST=aAHS->GetType();
if (aST==GeomAbs_Cone) {
gp_Cone aCone=aAHS->Cone();
Standard_Integer i;
Standard_Real aX[4], aXE;
//
aCone.Location().Coord(aX[0], aX[1], aX[2]);
aX[3]=aCone.RefRadius();
aXEmax=-1.;
for (i=0; i<4; ++i) {
if (aX[i]<0.) {
aX[i]=-aX[i];
}
aXE=Epsilon(aX[i]);
if (aXE>aXEmax) {
aXEmax=aXE;
}
}
}//if (aST==GeomAbs_Cone) {
aXC = BRepCheck::PrecCurve(aAC3D);
aXS = BRepCheck::PrecSurface(aAHS);
aXEmax = (aXC>aXS) ? aXC: aXS;
return aXEmax;
}
//=======================================================================
//function : PrintProblematicPoint
//purpose :

View File

@@ -62,6 +62,7 @@
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_DataMapOfIntegerShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
@@ -250,7 +251,7 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
TopoDS_Shape aux;
TheProf = myProfile;
TheProf.Location(Loc2.Multiplied(Loc1));
// Construct First && Last Shape
Handle(GeomFill_LocationLaw) law;
@@ -307,7 +308,7 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
}
#endif
myShape = MakeShape(TheProf, myFirst, myLast);
myShape = MakeShape(TheProf, myProfile, myFirst, myLast);
}
@@ -382,36 +383,8 @@ void BRepFill_Pipe::Generated(const TopoDS_Shape& theShape,
{
theList.Clear();
if (theShape.IsSame(myProfile))
theList.Append(myShape);
else
{
if (theShape.ShapeType() == TopAbs_FACE ||
theShape.ShapeType() == TopAbs_WIRE)
{
if(myGenMap.IsBound(theShape))
theList = myGenMap.Find(theShape);
}
else if (theShape.ShapeType() == TopAbs_EDGE)
{
TopoDS_Iterator itw(mySpine);
for (; itw.More(); itw.Next())
{
const TopoDS_Edge& aSpineEdge = TopoDS::Edge(itw.Value());
const TopoDS_Shape& aFace = Face(aSpineEdge, TopoDS::Edge(theShape));
theList.Append(aFace);
}
}
else if (theShape.ShapeType() == TopAbs_VERTEX)
{
TopoDS_Iterator itw(mySpine);
for (; itw.More(); itw.Next())
{
const TopoDS_Edge& aSpineEdge = TopoDS::Edge(itw.Value());
const TopoDS_Shape& anEdge = Edge(aSpineEdge, TopoDS::Vertex(theShape));
theList.Append(anEdge);
}
}
if(myGenMap.IsBound(theShape)) {
theList = myGenMap.Find(theShape);
}
}
@@ -540,9 +513,9 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
P = Point;
P.Transform(myTrsf);
BRepLib_MakeVertex MkV(P);
TopoDS_Vertex VertexSection = BRepLib_MakeVertex(P);
Handle(BRepFill_ShapeLaw) Section =
new (BRepFill_ShapeLaw) (MkV.Vertex());
new (BRepFill_ShapeLaw) (VertexSection);
// Sweeping
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
@@ -551,6 +524,7 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
TopoDS_Shape aLocalShape = MkSw.Shape();
myErrorOnSurf = MkSw.ErrorOnSurface();
BuildHistory(MkSw, VertexSection);
return TopoDS::Wire(aLocalShape);
// return TopoDS::Wire(MkSw.Shape());
}
@@ -561,6 +535,7 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
//=======================================================================
TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
const TopoDS_Shape& theOriginalS,
const TopoDS_Shape& FirstShape,
const TopoDS_Shape& LastShape)
{
@@ -574,6 +549,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
TheLast = LastShape;
if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
TopLoc_Location BackLoc(myTrsf.Inverted());
// there are two kinds of generation
// 1. generate with S from each Filler (Vertex, Edge)
// 2. call MakeShape recursively on the subshapes of S
@@ -658,13 +635,15 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
if (!TheLast.IsNull()) itLast.Initialize(TheLast);
for (TopoDS_Iterator it(S); it.More(); it.Next()) {
TopoDS_Iterator it(S);
TopoDS_Iterator itorig(theOriginalS);
for (; it.More(); it.Next(),itorig.Next()) {
if (!TheFirst.IsNull()) first = itFirst.Value();
if (!TheLast.IsNull()) last = itLast.Value();
if (TheS.ShapeType() == TopAbs_FACE )
MakeShape(it.Value(), first, last);
MakeShape(it.Value(), itorig.Value(), first, last);
else
B.Add(result,MakeShape(it.Value(), first, last));
B.Add(result,MakeShape(it.Value(), itorig.Value(), first, last));
if (!TheFirst.IsNull()) itFirst.Next();
if (!TheLast.IsNull()) itLast.Next();
@@ -680,7 +659,7 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
MkSw.Build( myReversedEdges, myTapes, myRails,
BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
UpdateMap(theOriginalS, result, myGenMap);
myErrorOnSurf = MkSw.ErrorOnSurface();
Handle(TopTools_HArray2OfShape) aSections = MkSw.Sections();
@@ -691,6 +670,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
myFirst = aSections->Value(1, 1);
myLast = aSections->Value(1, aVLast);
}
BuildHistory(MkSw, theOriginalS);
}
if (TheS.ShapeType() == TopAbs_WIRE ) {
@@ -703,7 +684,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
MkSw.Build( myReversedEdges, myTapes, myRails,
BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
myErrorOnSurf = MkSw.ErrorOnSurface();
// Labeling of elements
@@ -762,6 +742,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
myEdges = Somme;
}
BuildHistory(MkSw, theOriginalS);
}
}
@@ -808,7 +790,7 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
BS.Add(solid,TopoDS::Shell(aLocalShape));
// BS.Add(solid,TopoDS::Shell(result.Reversed()));
}
UpdateMap(TheS.Located(myProfile.Location()), solid, myGenMap);
UpdateMap(theOriginalS, solid, myGenMap);
return solid;
}
else {
@@ -1030,3 +1012,110 @@ void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace,
}
}
}
//=======================================================================
//function : BuildHistory
//purpose : Builds history for edges and vertices
// of section and path
//=======================================================================
void BRepFill_Pipe::BuildHistory(const BRepFill_Sweep& theSweep,
const TopoDS_Shape& theSection)
{
//Filling of <myGenMap>
const Handle(TopTools_HArray2OfShape)& anUEdges = theSweep.InterFaces();
Standard_Integer inde;
TopoDS_Iterator itw;
if (theSection.ShapeType() == TopAbs_WIRE)
{
TopoDS_Wire aSection = TopoDS::Wire(theSection);
BRepTools_WireExplorer wexp_sec(aSection);
for (inde = 0; wexp_sec.More(); wexp_sec.Next())
{
inde++;
const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current());
if (BRep_Tool::Degenerated(anEdge))
continue;
if (myGenMap.IsBound(anEdge))
continue;
TopoDS_Vertex aVertex [2];
TopExp::Vertices(anEdge, aVertex[0], aVertex[1]);
//For an edge generated shape is a "tape" -
//a shell usually containing this edge and
//passing from beginning of path to its end
TopoDS_Shell aTape = TopoDS::Shell(theSweep.Tape(inde));
//Processing of vertices of <anEdge>
//We should choose right index in <anUEdges>
//for each vertex of edge
Standard_Integer UIndex [2];
UIndex[0] = inde;
UIndex[1] = inde+1;
if (anEdge.Orientation() == TopAbs_REVERSED)
{ Standard_Integer Tmp = UIndex[0]; UIndex[0] = UIndex[1]; UIndex[1] = Tmp; }
for (Standard_Integer kk = 0; kk < 2; kk++)
{
if (myGenMap.IsBound(aVertex[kk]))
continue;
//Assemble the list of edges ("rail" along the path)
TopTools_ListOfShape* Elist = myGenMap.Bound(aVertex[kk], TopTools_ListOfShape());
Standard_Integer jj;
for (jj = 1; jj <= anUEdges->UpperCol(); jj++)
{
const TopoDS_Shape& anUedge = anUEdges->Value(UIndex[kk], jj);
if (!anUedge.IsNull())
Elist->Append(anUedge);
}
} //for (Standard_Integer kk = 0; kk < 2; kk++)
TopTools_ListOfShape* Flist = myGenMap.Bound(anEdge, TopTools_ListOfShape());
TopoDS_Iterator itsh(aTape);
for (; itsh.More(); itsh.Next())
Flist->Append(itsh.Value());
} //for (inde = 0; wexp_sec.More(); wexp_sec.Next())
} //if (theSection.ShapeType() == TopAbs_WIRE)
//For subshapes of spine
const Handle(TopTools_HArray2OfShape)& aFaces = theSweep.SubShape();
const Handle(TopTools_HArray2OfShape)& aVEdges = theSweep.Sections();
BRepTools_WireExplorer wexp(mySpine);
inde = 0;
Standard_Boolean ToExit = Standard_False;
for (;;)
{
if (!wexp.More())
ToExit = Standard_True;
inde++;
if (!ToExit)
{
const TopoDS_Edge& anEdgeOfSpine = wexp.Current();
for (Standard_Integer i = 1; i <= aFaces->UpperRow(); i++)
{
const TopoDS_Shape& aFace = aFaces->Value(i, inde);
UpdateMap(anEdgeOfSpine, aFace, myGenMap);
}
}
const TopoDS_Vertex& aVertexOfSpine = wexp.CurrentVertex();
for (Standard_Integer i = 1; i <= aVEdges->UpperRow(); i++)
{
const TopoDS_Shape& aVedge = aVEdges->Value(i, inde);
UpdateMap(aVertexOfSpine, aVedge, myGenMap);
}
if (ToExit)
break;
if (wexp.More())
wexp.Next();
}
}

View File

@@ -42,6 +42,7 @@ class TopoDS_Face;
class TopoDS_Edge;
class TopoDS_Vertex;
class gp_Pnt;
class BRepFill_Sweep;
//! Create a shape by sweeping a shape (the profile)
@@ -59,9 +60,15 @@ public:
Standard_EXPORT BRepFill_Pipe();
Standard_EXPORT BRepFill_Pipe(const TopoDS_Wire& Spine, const TopoDS_Shape& Profile, const GeomFill_Trihedron aMode = GeomFill_IsCorrectedFrenet, const Standard_Boolean ForceApproxC1 = Standard_False, const Standard_Boolean GeneratePartCase = Standard_False);
Standard_EXPORT BRepFill_Pipe(const TopoDS_Wire& Spine,
const TopoDS_Shape& Profile,
const GeomFill_Trihedron aMode = GeomFill_IsCorrectedFrenet,
const Standard_Boolean ForceApproxC1 = Standard_False,
const Standard_Boolean GeneratePartCase = Standard_False);
Standard_EXPORT void Perform (const TopoDS_Wire& Spine, const TopoDS_Shape& Profile, const Standard_Boolean GeneratePartCase = Standard_False);
Standard_EXPORT void Perform (const TopoDS_Wire& Spine,
const TopoDS_Shape& Profile,
const Standard_Boolean GeneratePartCase = Standard_False);
Standard_EXPORT const TopoDS_Shape& Spine() const;
@@ -113,22 +120,27 @@ private:
//! Auxiliary recursive method used to build the
//! result.
Standard_EXPORT TopoDS_Shape MakeShape (const TopoDS_Shape& S, const TopoDS_Shape& FirstShape, const TopoDS_Shape& LastShape);
Standard_EXPORT TopoDS_Shape MakeShape (const TopoDS_Shape& S,
const TopoDS_Shape& theOriginalS,
const TopoDS_Shape& FirstShape,
const TopoDS_Shape& LastShape);
//! Auxiliary recursive method used to find the edge's index
Standard_EXPORT Standard_Integer FindEdge (const TopoDS_Shape& S, const TopoDS_Edge& E, Standard_Integer& Init) const;
Standard_EXPORT Standard_Integer FindEdge (const TopoDS_Shape& S,
const TopoDS_Edge& E,
Standard_Integer& Init) const;
Standard_EXPORT Standard_Integer FindVertex (const TopoDS_Shape& S, const TopoDS_Vertex& V, Standard_Integer& Init) const;
Standard_EXPORT Standard_Integer FindVertex (const TopoDS_Shape& S, const
TopoDS_Vertex& V,
Standard_Integer& Init) const;
Standard_EXPORT void DefineRealSegmax();
Standard_EXPORT void RebuildTopOrBottomFace (const TopoDS_Shape& aFace, const Standard_Boolean IsTop) const;
Standard_EXPORT void RebuildTopOrBottomFace (const TopoDS_Shape& aFace,
const Standard_Boolean IsTop) const;
//! Performs sharing coincident faces in theShape. Also modifies
//! myFaces, mySections and myEdges to contain shared shapes.
//! Returns the shared shape. If theShape is not modified this
//! method returns it.
Standard_EXPORT TopoDS_Shape ShareFaces (const TopoDS_Shape& theShape, const Standard_Integer theInitialFacesLen, const Standard_Integer theInitialEdgesLen, const Standard_Integer theInitialSectionsLen);
Standard_EXPORT void BuildHistory (const BRepFill_Sweep& theSweep,
const TopoDS_Shape& theSection);
TopoDS_Wire mySpine;

View File

@@ -1203,8 +1203,8 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec,
//=======================================================================
//function : BuildHistory
//purpose : Builds history for edges and vertices
// of sections
//purpose : Builds history for edges and vertices of sections,
// for edges and vertices of spine
//=======================================================================
void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
{
@@ -1226,11 +1226,11 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
//for punctual sections (first or last)
//we take all the wires generated along the path
TopTools_ListOfShape Elist;
TopTools_ListOfShape* Elist = myGenMap.Bound(Section, TopTools_ListOfShape());
for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++)
for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++)
Elist.Append(anUEdges->Value(i,j));
myGenMap.Bind(Section, Elist);
Elist->Append(anUEdges->Value(i,j));
continue;
}
else
@@ -1319,9 +1319,11 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
continue;
if (IndWireMap.IsBound(UIndex[kk]))
{
TopTools_ListOfShape Wlist;
Wlist.Append(IndWireMap(UIndex[kk]));
myGenMap.Bind(aVertex[kk], Wlist);
TopTools_ListOfShape* Elist = myGenMap.Bound(aVertex[kk], TopTools_ListOfShape());
for (itw.Initialize( IndWireMap(UIndex[kk]) ); itw.More(); itw.Next())
Elist->Append(itw.Value());
continue;
}
@@ -1393,22 +1395,88 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
}
}
}
TopTools_ListOfShape Wlist;
Wlist.Append(aWire);
myGenMap.Bind(aVertex[kk], Wlist);
TopTools_ListOfShape* Elist = myGenMap.Bound(aVertex[kk], TopTools_ListOfShape());
for (itw.Initialize(aWire); itw.More(); itw.Next())
Elist->Append(itw.Value());
//Save already built wire with its index
IndWireMap.Bind(UIndex[kk], aWire);
} //for (Standard_Integer kk = 0; kk < 2; kk++)
////////////////////////////////////
TopTools_ListOfShape ListShell;
ListShell.Append(aShell);
myGenMap.Bind(anOriginalEdge, ListShell);
TopTools_ListOfShape* Flist = myGenMap.Bound(anOriginalEdge, TopTools_ListOfShape());
TopoDS_Iterator itsh(aShell);
for (; itsh.More(); itsh.Next())
Flist->Append(itsh.Value());
////////////////////////
inde++;
}
}
//For subshapes of spine
const Handle(TopTools_HArray2OfShape)& aFaces = theSweep.SubShape();
const Handle(TopTools_HArray2OfShape)& aVEdges = theSweep.Sections();
BRepTools_WireExplorer wexp(mySpine);
inde = 0;
Standard_Boolean ToExit = Standard_False;
for (;;)
{
if (!wexp.More())
ToExit = Standard_True;
inde++;
if (!ToExit)
{
const TopoDS_Edge& anEdgeOfSpine = wexp.Current();
TopTools_ListOfShape* Flist = myGenMap.Bound(anEdgeOfSpine, TopTools_ListOfShape());
for (Standard_Integer i = 1; i <= aFaces->UpperRow(); i++)
{
const TopoDS_Shape& aFace = aFaces->Value(i, inde);
if (aFace.ShapeType() == TopAbs_FACE)
Flist->Append(aFace);
}
}
const TopoDS_Vertex& aVertexOfSpine = wexp.CurrentVertex();
TopTools_ListOfShape* ListVshapes = myGenMap.Bound(aVertexOfSpine, TopTools_ListOfShape());
for (Standard_Integer i = 1; i <= aVEdges->UpperRow(); i++)
{
const TopoDS_Shape& aVshape = aVEdges->Value(i, inde);
if (aVshape.ShapeType() == TopAbs_EDGE ||
aVshape.ShapeType() == TopAbs_FACE)
ListVshapes->Append(aVshape);
else
{
TopoDS_Iterator itvshape(aVshape);
for (; itvshape.More(); itvshape.Next())
{
const TopoDS_Shape& aSubshape = itvshape.Value();
if (aSubshape.ShapeType() == TopAbs_EDGE ||
aSubshape.ShapeType() == TopAbs_FACE)
ListVshapes->Append(aSubshape);
else
{
//it is wire
for (itw.Initialize(aSubshape); itw.More(); itw.Next())
ListVshapes->Append(itw.Value());
}
}
}
}
if (ToExit)
break;
if (wexp.More())
wexp.Next();
}
}

View File

@@ -192,6 +192,12 @@ public:
theProfiles.Append(mySeq(i).OriginalShape());
}
//! Returns the spine
const TopoDS_Wire& Spine()
{
return mySpine;
}
//! Returns the list of shapes generated from the
//! shape <S>.
Standard_EXPORT void Generated (const TopoDS_Shape& S, TopTools_ListOfShape& L);

View File

@@ -2938,9 +2938,10 @@ void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
// Management of looping ends
if ( (NbTrous>0) && (myLoc->IsClosed()) &&
(Trous->Value(NbTrous) == NbPath+1) ) {
Translate(myVEdges, NbPath+1, Bounds, 1);
Translate(myVEdges, 1, Bounds, 2);
Translate(myVEdges, NbPath+1, Bounds, 1);
Translate(myVEdges, 1, Bounds, 2);
PerformCorner(1, Transition, Bounds);
Translate(myVEdges, 1, myVEdges, NbPath+1);
}
// Construction of the shell
@@ -3038,7 +3039,8 @@ void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++)
{
TopoDS_Edge anEdge = TopoDS::Edge(myUEdges->Value(ii, jj));
if (anEdge.IsNull())
if (anEdge.IsNull() ||
BRep_Tool::Degenerated(anEdge))
continue;
TopoDS_Face Face1, Face2;
Standard_Integer i1 = ii-1, i2 = ii;
@@ -3047,10 +3049,19 @@ void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
if (i2 > myFaces->UpperRow())
i2 = 0;
if (i1 != 0)
Face1 = TopoDS::Face(myFaces->Value(i1, jj));
{
const TopoDS_Shape& aShape1 = myFaces->Value(i1, jj);
if (aShape1.ShapeType() == TopAbs_FACE)
Face1 = TopoDS::Face(aShape1);
}
if (i2 != 0)
Face2 = TopoDS::Face(myFaces->Value(i2, jj));
CorrectSameParameter(anEdge, Face1, Face2);
{
const TopoDS_Shape& aShape2 = myFaces->Value(i2, jj);
if (aShape2.ShapeType() == TopAbs_FACE)
Face2 = TopoDS::Face(aShape2);
}
if (!Face1.IsNull() && !Face2.IsNull())
CorrectSameParameter(anEdge, Face1, Face2);
}
}
@@ -3263,10 +3274,27 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const
BRepFill_TrimShellCorner aTrim(aFaces, Transition, AxeOfBisPlane);
aTrim.AddBounds(Bounds);
aTrim.AddUEdges(aUEdges);
aTrim.AddVEdges(myVEdges, Index);
aTrim.Perform();
if (aTrim.IsDone()) {
TopTools_ListOfShape listmodif;
for (ii = 1; ii <= mySec->NbLaw(); ii++)
{
listmodif.Clear();
aTrim.Modified(myVEdges->Value(ii, Index), listmodif);
if (listmodif.IsEmpty())
{
TopoDS_Edge NullEdge;
myVEdges->SetValue(ii, Index, NullEdge);
}
else
myVEdges->SetValue(ii, Index, listmodif.First());
}
listmodif.Clear();
Standard_Integer iit = 0;
for(iit = 0; iit < 2; iit++) {
@@ -3353,8 +3381,15 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const
if (B) {
myAuxShape.Append(FF);
myVEdges->ChangeValue(ii, I2) = FF;
BRep_Builder BB;
TopoDS_Shape aVshape = myVEdges->Value(ii, I2);
TopoDS_Compound aCompound;
BB.MakeCompound(aCompound);
if (!aVshape.IsNull())
BB.Add(aCompound, aVshape);
BB.Add(aCompound, FF);
myVEdges->ChangeValue(ii, I2) = aCompound;
BB.Add(myTapes->ChangeValue(ii), FF);
HasFilling = Standard_True;
}

View File

@@ -91,6 +91,11 @@ static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& t
const BOPDS_PDS& theDS,
TopTools_DataMapOfShapeListOfShape& theHistMap);
static void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
const Standard_Integer theIndex,
const TopoDS_Shape& theNewVedge,
TopTools_DataMapOfShapeListOfShape& theHistMap);
static void FindFreeVertices(const TopoDS_Shape& theShape,
const TopTools_MapOfShape& theVerticesToAvoid,
TopTools_ListOfShape& theListOfVertex);
@@ -229,6 +234,19 @@ void BRepFill_TrimShellCorner::AddUEdges(const Handle(TopTools_HArray2OfShape)&
myUEdges->ChangeArray2() = theUEdges->Array2();
}
// ===========================================================================================
// function: AddVEdges
// purpose:
// ===========================================================================================
void BRepFill_TrimShellCorner::AddVEdges(const Handle(TopTools_HArray2OfShape)& theVEdges,
const Standard_Integer theIndex)
{
myVEdges = new TopTools_HArray1OfShape(theVEdges->LowerRow(), theVEdges->UpperRow());
for (Standard_Integer i = theVEdges->LowerRow(); i <= theVEdges->UpperRow(); i++)
myVEdges->SetValue(i, theVEdges->Value(i, theIndex));
}
// ===========================================================================================
// function: Perform
// purpose:
@@ -479,9 +497,12 @@ BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer
aMapV.Add(aV);
aBB.Add(aComp, aUE);
}
if(bHasNewEdge) {
aBB.Add(aComp, aNewEdge);
StoreVedgeInHistMap(myVEdges, theIndex, aNewEdge, myHistMap);
}
TopTools_ListOfShape alonevertices;
FindFreeVertices(aComp, aMapV, alonevertices);
@@ -686,6 +707,8 @@ BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer
for (; explo.More(); explo.Next())
BB.Add( aComp, explo.Current() );
aSecEdges = aComp;
StoreVedgeInHistMap(myVEdges, theIndex, SecWire, myHistMap);
}
TopTools_ListOfShape aCommonVertices;
@@ -1123,6 +1146,22 @@ Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdge
return Standard_True;
}
// ------------------------------------------------------------------------------------------
// static function: StoreVedgeInHistMap
// purpose:
// ------------------------------------------------------------------------------------------
void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
const Standard_Integer theIndex,
const TopoDS_Shape& theNewVshape,
TopTools_DataMapOfShapeListOfShape& theHistMap)
{
//Replace default value in the map (v-iso edge of face)
//by intersection of two consecutive faces
const TopoDS_Shape& aVEdge = theVEdges->Value(theIndex);
theHistMap.Bound(aVEdge, TopTools_ListOfShape())->Append(theNewVshape);
}
// ------------------------------------------------------------------------------------------
// static function: FindFreeVertices
// purpose:

View File

@@ -26,6 +26,7 @@
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopTools_HArray2OfShape.hxx>
#include <TopTools_HArray1OfShape.hxx>
#include <Standard_Boolean.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
@@ -55,6 +56,9 @@ public:
Standard_EXPORT void AddUEdges (const Handle(TopTools_HArray2OfShape)& theUEdges);
Standard_EXPORT void AddVEdges (const Handle(TopTools_HArray2OfShape)& theVEdges,
const Standard_Integer theIndex);
Standard_EXPORT void Perform();
Standard_EXPORT Standard_Boolean IsDone() const;
@@ -99,6 +103,7 @@ private:
TopoDS_Shape myShape2;
Handle(TopTools_HArray2OfShape) myBounds;
Handle(TopTools_HArray2OfShape) myUEdges;
Handle(TopTools_HArray1OfShape) myVEdges;
Handle(TopTools_HArray2OfShape) myFaces;
Standard_Boolean myDone;
Standard_Boolean myHasSection;

View File

@@ -29,6 +29,7 @@
#include <BRep_GCurve.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <BRep_ListOfCurveRepresentation.hxx>
#include <BRepCheck.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_TFace.hxx>
#include <BRep_Tool.hxx>
@@ -1311,6 +1312,8 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
}
GAC.Load(C3d,f3d,l3d);
Standard_Real Prec_C3d = BRepCheck::PrecCurve(GAC);
Standard_Boolean IsSameP = 1;
Standard_Real maxdist = 0.;
@@ -1597,7 +1600,9 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
// Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin
if (!IsSameP) {
if (anEdgeTol >= error) {
Standard_Real Prec_Surf = BRepCheck::PrecSurface(HS);
Standard_Real CurTol = anEdgeTol + Max(Prec_C3d, Prec_Surf);
if (CurTol >= error) {
maxdist = Max(maxdist, anEdgeTol);
IsSameP = Standard_True;
}

View File

@@ -267,7 +267,11 @@ public:
myPipe->Profiles(theProfiles);
}
//! Returns the spine
const TopoDS_Wire& Spine()
{
return myPipe->Spine();
}
protected:

View File

@@ -298,9 +298,25 @@ static Standard_Integer checksection(Draw_Interpretor& di,
Standard_Integer narg, const char** a)
{
if (narg < 2) {
di << a[0] << " shape [-r <ref_val>]\n";
return 1;
}
Standard_Integer aCompareValue = -1;
TopoDS_Shape S = DBRep::Get(a[1]);
for (Standard_Integer anAI = 2; anAI < narg; anAI++)
{
if (!strcmp(a[anAI], "-r"))
{
aCompareValue = Draw::Atoi(a[++anAI]);
}
else
{
di << "Error: Wrong option" << a[anAI] << "\n";
}
}
TopTools_MapOfShape theVertices;
TopExp_Explorer exp;
for (exp.Init(S, TopAbs_VERTEX); exp.More(); exp.Next()) {
@@ -309,6 +325,20 @@ static Standard_Integer checksection(Draw_Interpretor& di,
}
//cout << " nb alone Vertices : " << theVertices.Extent() << endl;
di << " nb alone Vertices : " << theVertices.Extent() << "\n";
if (aCompareValue >= 0)
{
if (theVertices.Extent() == aCompareValue)
{
di << "Section is OK\n";
}
else
{
di << "Error: "<< aCompareValue << " vertices are expected but " <<
theVertices.Extent() << " are found.\n";
}
}
char Name[32];
Standard_Integer ipp=0;
TopTools_MapIteratorOfMapOfShape itvx;
@@ -1698,7 +1728,8 @@ void BRepTest::CheckCommands(Draw_Interpretor& theCommands)
// Modified by skv - Tue Apr 27 13:35:39 2004 End
theCommands.Add("checksection",
"checks the closure of a section : checksection name",
"checks the closure of a section : checksection name [-r <RefVal>]\n"
"\"-r\" - allowed number of allone vertices.",
__FILE__,
checksection,
g);

View File

@@ -164,10 +164,11 @@ static Standard_Integer pipe(Draw_Interpretor& di,
if (n >= 6)
ForceApproxC1 = Standard_True;
TopoDS_Shape S = BRepOffsetAPI_MakePipe(TopoDS::Wire(Spine),
Profile,
Mode,
ForceApproxC1);
BRepOffsetAPI_MakePipe PipeBuilder(TopoDS::Wire(Spine),
Profile,
Mode,
ForceApproxC1);
TopoDS_Shape S = PipeBuilder.Shape();
DBRep::Set(a[1],S);
@@ -769,9 +770,11 @@ static Standard_Integer buildsweep(Draw_Interpretor& di,
result = Sweep->Shape();
DBRep::Set(a[1],result);
// Save history of sweep
TopTools_ListOfShape aProfiles;
Sweep->Profiles(aProfiles);
BRepTest_Objects::SetHistory(aProfiles, *Sweep);
TopTools_ListOfShape aList;
Sweep->Profiles(aList);
TopoDS_Shape aSpine = Sweep->Spine();
aList.Append(aSpine);
BRepTest_Objects::SetHistory(aList, *Sweep);
}
return 0;

View File

@@ -26,82 +26,97 @@ static inline
const Standard_Real umaxmumin);
//=======================================================================
//function : CSLib_Class2d
//purpose :
//function : Init
//purpose :
//=======================================================================
CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& TP2d,
const Standard_Real aTolu,
const Standard_Real aTolv,
const Standard_Real umin,
const Standard_Real vmin,
const Standard_Real umax,
const Standard_Real vmax)
template <class TCol_Containers2d>
void CSLib_Class2d::Init(const TCol_Containers2d& TP2d,
const Standard_Real aTolu,
const Standard_Real aTolv,
const Standard_Real umin,
const Standard_Real vmin,
const Standard_Real umax,
const Standard_Real vmax)
{
Umin=umin;
Vmin=vmin;
Umax=umax;
Vmax=vmax;
Umin = umin;
Vmin = vmin;
Umax = umax;
Vmax = vmax;
//
if(umax<=umin || vmax<=vmin) {
MyPnts2dX=NULL;
MyPnts2dY=NULL;
N=0;
if ((umax <= umin) || (vmax <= vmin) || (TP2d.Length() < 3))
{
MyPnts2dX.Nullify();
MyPnts2dY.Nullify();
N = 0;
}
//
else {
else
{
Standard_Integer i, iLower;
Standard_Real du,dv,*Pnts2dX,*Pnts2dY, aPrc;
Standard_Real du, dv, aPrc;
//
aPrc=1.e-10;
aPrc = 1.e-10;
N = TP2d.Length();
Tolu = aTolu;
Tolv = aTolv;
MyPnts2dX = new Standard_Real [N+1];
MyPnts2dY = new Standard_Real [N+1];
du=umax-umin;
dv=vmax-vmin;
Pnts2dX = (Standard_Real *)MyPnts2dX;
Pnts2dY = (Standard_Real *)MyPnts2dY;
MyPnts2dX = new TColStd_Array1OfReal(0, N);
MyPnts2dY = new TColStd_Array1OfReal(0, N);
du = umax - umin;
dv = vmax - vmin;
//
iLower=TP2d.Lower();
for(i = 0; i<N; ++i) {
const gp_Pnt2d& aP2D=TP2d(i+iLower);
Pnts2dX[i] = Transform2d(aP2D.X(), umin, du);
Pnts2dY[i] = Transform2d(aP2D.Y(), vmin, dv);
iLower = TP2d.Lower();
for (i = 0; i<N; ++i)
{
const gp_Pnt2d& aP2D = TP2d(i + iLower);
MyPnts2dX->ChangeValue(i) = Transform2d(aP2D.X(), umin, du);
MyPnts2dY->ChangeValue(i) = Transform2d(aP2D.Y(), vmin, dv);
}
Pnts2dX[N]=Pnts2dX[0];
Pnts2dY[N]=Pnts2dY[0];
MyPnts2dX->ChangeLast() = MyPnts2dX->First();
MyPnts2dY->ChangeLast() = MyPnts2dY->First();
//
if(du>aPrc) {
Tolu/=du;
if (du>aPrc)
{
Tolu /= du;
}
if(dv>aPrc) {
Tolv/=dv;
if (dv>aPrc)
{
Tolv /= dv;
}
}
}
//=======================================================================
//function : Destroy
//purpose :
//=======================================================================
void CSLib_Class2d::Destroy() {
if(MyPnts2dX) {
delete [] (Standard_Real *)MyPnts2dX;
MyPnts2dX=NULL;
}
if(MyPnts2dY) {
delete [] (Standard_Real *)MyPnts2dY;
MyPnts2dY=NULL;
}
}
//-- Attention Table of 0 ------> N + 1
//-- P1 ..... Pn P1
//--
//-- 1 2 3
//-- 4 0 5
//-- 6 7 8
//--
//=======================================================================
//function : CSLib_Class2d
//purpose :
//=======================================================================
CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& thePnts2d,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Standard_Real theUMin,
const Standard_Real theVMin,
const Standard_Real theUMax,
const Standard_Real theVMax)
{
Init(thePnts2d, theTolU, theTolV, theUMin,
theVMin, theUMax, theVMax);
}
//=======================================================================
//function : CSLib_Class2d
//purpose :
//=======================================================================
CSLib_Class2d::CSLib_Class2d(const TColgp_SequenceOfPnt2d& thePnts2d,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Standard_Real theUMin,
const Standard_Real theVMin,
const Standard_Real theUMax,
const Standard_Real theVMax)
{
Init(thePnts2d, theTolU, theTolV, theUMin,
theVMin, theUMax, theVMax);
}
//=======================================================================
//function : SiDans
//purpose :
@@ -187,21 +202,18 @@ Standard_Integer CSLib_Class2d::InternalSiDans(const Standard_Real Px,
const Standard_Real Py) const
{
Standard_Integer nbc, i, ip1, SH, NH;
Standard_Real *Pnts2dX, *Pnts2dY;
Standard_Real x, y, nx, ny;
//
nbc = 0;
i = 0;
ip1 = 1;
Pnts2dX = (Standard_Real *)MyPnts2dX;
Pnts2dY = (Standard_Real *)MyPnts2dY;
x = (Pnts2dX[i]-Px);
y = (Pnts2dY[i]-Py);
x = (MyPnts2dX->Value(i)-Px);
y = (MyPnts2dY->Value(i)-Py);
SH = (y<0.)? -1 : 1;
//
for(i=0; i<N ; i++,ip1++) {
nx = Pnts2dX[ip1] - Px;
ny = Pnts2dY[ip1] - Py;
nx = MyPnts2dX->Value(ip1) - Px;
ny = MyPnts2dY->Value(ip1) - Py;
NH = (ny<0.)? -1 : 1;
if(NH!=SH) {
@@ -230,23 +242,20 @@ Standard_Integer CSLib_Class2d::InternalSiDansOuOn(const Standard_Real Px,
const Standard_Real Py) const
{
Standard_Integer nbc, i, ip1, SH, NH, iRet;
Standard_Real *Pnts2dX, *Pnts2dY;
Standard_Real x, y, nx, ny, aX;
Standard_Real aYmin;
//
nbc = 0;
i = 0;
ip1 = 1;
Pnts2dX = (Standard_Real *)MyPnts2dX;
Pnts2dY = (Standard_Real *)MyPnts2dY;
x = (Pnts2dX[i]-Px);
y = (Pnts2dY[i]-Py);
x = (MyPnts2dX->Value(i)-Px);
y = (MyPnts2dY->Value(i)-Py);
aYmin=y;
SH = (y<0.)? -1 : 1;
for(i=0; i<N ; i++, ip1++) {
nx = Pnts2dX[ip1] - Px;
ny = Pnts2dY[ip1] - Py;
nx = MyPnts2dX->Value(ip1) - Px;
ny = MyPnts2dY->Value(ip1) - Py;
//-- le 14 oct 97
if(nx<Tolu && nx>-Tolu && ny<Tolv && ny>-Tolv) {
iRet=-1;
@@ -254,11 +263,11 @@ Standard_Integer CSLib_Class2d::InternalSiDansOuOn(const Standard_Real Px,
}
//find Y coordinate of polyline for current X gka
//in order to detect possible status ON
Standard_Real aDx = (Pnts2dX[ip1] - Pnts2dX[ip1-1]);
if( (Pnts2dX[ip1-1] - Px) * nx < 0.)
Standard_Real aDx = (MyPnts2dX->Value(ip1) - MyPnts2dX->Value(ip1-1));
if( (MyPnts2dX->Value(ip1-1) - Px) * nx < 0.)
{
Standard_Real aCurPY = Pnts2dY[ip1] - (Pnts2dY[ip1] - Pnts2dY[ip1-1])/aDx *nx;
Standard_Real aCurPY = MyPnts2dY->Value(ip1) - (MyPnts2dY->Value(ip1) - MyPnts2dY->Value(ip1-1))/aDx *nx;
Standard_Real aDeltaY = aCurPY - Py;
if(aDeltaY >= -Tolv && aDeltaY <= Tolv)
{
@@ -296,17 +305,6 @@ Standard_Integer CSLib_Class2d::InternalSiDansOuOn(const Standard_Real Px,
}
//modified by NIZNHY-PKV Fri Jan 15 09:03:55 2010t
//=======================================================================
//function : Copy
//purpose :
//=======================================================================
const CSLib_Class2d& CSLib_Class2d::Copy(const CSLib_Class2d& ) const
{
#ifdef OCCT_DEBUG
cerr<<"Copy not allowed in CSLib_Class2d"<<endl;
#endif
throw Standard_ConstructionError();
}
//=======================================================================
//function : Transform2d
//purpose :
//=======================================================================

View File

@@ -25,6 +25,10 @@
#include <Standard_Real.hxx>
#include <Standard_Integer.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <NCollection_Handle.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColgp_SequenceOfPnt2d.hxx>
class gp_Pnt2d;
@@ -38,8 +42,38 @@ public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT CSLib_Class2d(const TColgp_Array1OfPnt2d& TP, const Standard_Real aTolu, const Standard_Real aTolv, const Standard_Real umin, const Standard_Real vmin, const Standard_Real umax, const Standard_Real vmax);
//! Constructs the 2D-polygon.
//! thePnts2d is the set of the vertices (closed polygon
//! will always be created inside of this constructor;
//! consequently, there is no point in repeating first and
//! last point in thePnts2d).
//! theTolu and theTolv are tolerances.
//! theUmin, theVmin, theUmax, theVmax are
//! UV-bounds of the polygon.
Standard_EXPORT CSLib_Class2d(const TColgp_Array1OfPnt2d& thePnts2d,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Standard_Real theUMin,
const Standard_Real theVMin,
const Standard_Real theUMax,
const Standard_Real theVMax);
//! Constructs the 2D-polygon.
//! thePnts2d is the set of the vertices (closed polygon
//! will always be created inside of this constructor;
//! consequently, there is no point in repeating first and
//! last point in thePnts2d).
//! theTolu and theTolv are tolerances.
//! theUmin, theVmin, theUmax, theVmax are
//! UV-bounds of the polygon.
Standard_EXPORT CSLib_Class2d(const TColgp_SequenceOfPnt2d& thePnts2d,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Standard_Real theUMin,
const Standard_Real theVMin,
const Standard_Real theUMax,
const Standard_Real theVMax);
Standard_EXPORT Standard_Integer SiDans (const gp_Pnt2d& P) const;
Standard_EXPORT Standard_Integer SiDans_OnMode (const gp_Pnt2d& P, const Standard_Real Tol) const;
@@ -48,33 +82,25 @@ public:
Standard_EXPORT Standard_Integer InternalSiDansOuOn (const Standard_Real X, const Standard_Real Y) const;
Standard_EXPORT const CSLib_Class2d& Copy (const CSLib_Class2d& Other) const;
const CSLib_Class2d& operator= (const CSLib_Class2d& Other) const
{
return Copy(Other);
}
Standard_EXPORT void Destroy();
~CSLib_Class2d()
{
Destroy();
}
protected:
private:
//! Initializes theObj
template <class TCol_Containers2d>
void Init(const TCol_Containers2d& TP2d,
const Standard_Real aTolu,
const Standard_Real aTolv,
const Standard_Real umin,
const Standard_Real vmin,
const Standard_Real umax,
const Standard_Real vmax);
//! Assign operator is forbidden
const CSLib_Class2d& operator= (const CSLib_Class2d& Other) const;
Standard_Address MyPnts2dX;
Standard_Address MyPnts2dY;
NCollection_Handle <TColStd_Array1OfReal> MyPnts2dX, MyPnts2dY;
Standard_Real Tolu;
Standard_Real Tolv;
Standard_Integer N;

View File

@@ -40,7 +40,7 @@ class Geom_ConicalSurface;
DEFINE_STANDARD_HANDLE(Geom_ConicalSurface, Geom_ElementarySurface)
//! Describes a cone.
//! A cone is defined by the half-angle at its apex, and
//! A cone is defined by the half-angle (can be negative) at its apex, and
//! is positioned in space by a coordinate system (a
//! gp_Ax3 object) and a reference radius as follows:
//! - The "main Axis" of the coordinate system is the
@@ -79,7 +79,8 @@ public:
//! A3 defines the local coordinate system of the conical surface.
//! Ang is the conical surface semi-angle ]0, PI/2[.
//! Ang is the conical surface semi-angle. Its absolute value is in range
//! ]0, PI/2[.
//! Radius is the radius of the circle Viso in the placement plane
//! of the conical surface defined with "XAxis" and "YAxis".
//! The "ZDirection" of A3 defines the direction of the surface's
@@ -90,8 +91,8 @@ public:
//! such that the normal Vector (N = D1U ^ D1V) is oriented towards
//! the "outside region" of the surface.
//!
//! Raised if Radius < 0.0 or Ang < Resolution from gp or
//! Ang >= PI/2 - Resolution
//! Raised if Radius < 0.0 or Abs(Ang) < Resolution from gp or
//! Abs(Ang) >= PI/2 - Resolution
Standard_EXPORT Geom_ConicalSurface(const gp_Ax3& A3, const Standard_Real Ang, const Standard_Real Radius);
@@ -112,9 +113,11 @@ public:
//! Changes the semi angle of the conical surface.
//!
//! Raised if Ang < Resolution or Ang >= PI/2 - Resolution
Standard_EXPORT void SetSemiAngle (const Standard_Real Ang);
//! Semi-angle can be negative. Its absolute value
//! Abs(Ang) is in range ]0,PI/2[.
//! Raises ConstructionError if Abs(Ang) < Resolution from gp or
//! Abs(Ang) >= PI/2 - Resolution
Standard_EXPORT void SetSemiAngle(const Standard_Real Ang);
//! returns a non transient cone with the same geometric properties
@@ -206,7 +209,8 @@ public:
Standard_EXPORT Standard_Real RefRadius() const;
//! returns the semi-angle of the conical surface ]0.0, PI/2[.
//! Returns the semi-angle at the apex of this cone.
//! Attention! Semi-angle can be negative.
Standard_EXPORT Standard_Real SemiAngle() const;
//! returns True.

View File

@@ -14,6 +14,7 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <algorithm>
#include <Adaptor2d_HCurve2d.hxx>
#include <Adaptor3d_TopolTool.hxx>
@@ -41,96 +42,83 @@
#include <TColStd_IndexedMapOfInteger.hxx>
#include <TopAbs_Orientation.hxx>
static
void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
const gp_Pnt& Ptref,
Standard_Real& U1,
Standard_Real& V1);
static
void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
const Handle(GeomAdaptor_HSurface)& myHS2,
const gp_Pnt& Ptref,
Standard_Real& U1,
Standard_Real& V1,
Standard_Real& U2,
Standard_Real& V2);
static const Standard_Real TwoPI = M_PI + M_PI;
static
void GLinePoint(const IntPatch_IType typl,
const Handle(IntPatch_GLine)& GLine,
const Standard_Real aT,
gp_Pnt& aP);
static
void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
const Handle(GeomAdaptor_HSurface)& myHS2,
Standard_Real& u1,
Standard_Real& v1,
Standard_Real& u2,
Standard_Real& v2);
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//
//=======================================================================
//class : GeomInt_RealWithFlag
//purpose :
//class : GeomInt_Vertex
//purpose : This class has been created in order to provide possibility
// to sort IntPatch_Points by their parameter on line.
//=======================================================================
class GeomInt_RealWithFlag {
public:
GeomInt_RealWithFlag() :
myValue(-99.), myFlag(1)
class GeomInt_Vertex
{
public:
GeomInt_Vertex()
{
};
//
~GeomInt_RealWithFlag() {
};
//
void SetValue(const Standard_Real aT) {
myValue=aT;
};
//
Standard_Real Value() const {
return myValue;
//! Initializes this class by IntPatch_Point
void SetVertex(const IntPatch_Point& theOther)
{
myVertex = theOther;
const Standard_Real aNewParam = ElCLib::InPeriod(theOther.ParameterOnLine(), 0.0, TwoPI);
SetParameter(aNewParam);
}
//
void SetFlag(const Standard_Integer aFlag) {
myFlag=aFlag;
};
//
Standard_Integer Flag() const {
return myFlag;
//! Sets Parameter on Line
void SetParameter(const Standard_Real theParam)
{
myVertex.SetParameter(theParam);
}
//
Standard_Boolean operator < (const GeomInt_RealWithFlag& aOther) {
return myValue<aOther.myValue;
//! Returns IntPatch_Point
const IntPatch_Point& Getvertex() const
{
return myVertex;
}
//
protected:
Standard_Real myValue;
Standard_Integer myFlag;
//! To provide sort
Standard_Boolean operator < (const GeomInt_Vertex& theOther) const
{
return myVertex.ParameterOnLine() < theOther.myVertex.ParameterOnLine();
}
private:
IntPatch_Point myVertex;
};
//------------
static
void SortShell(const Standard_Integer,
GeomInt_RealWithFlag *);
static
void RejectDuplicates(Standard_Integer& aNbVtx,
GeomInt_RealWithFlag *pVtx,
Standard_Real aTolPrm);
static
void RejectNearBeacons(Standard_Integer& aNbVtx,
GeomInt_RealWithFlag *pVtx,
Standard_Real aTolPC1,
const GeomAbs_SurfaceType aTS1,
const GeomAbs_SurfaceType aTS2);
static
Standard_Real AdjustOnPeriod(const Standard_Real aTr,
const Standard_Real aPeriod);
static void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
const gp_Pnt& Ptref,
Standard_Real& U1,
Standard_Real& V1);
static void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
const Handle(GeomAdaptor_HSurface)& myHS2,
const gp_Pnt& Ptref,
Standard_Real& U1,
Standard_Real& V1,
Standard_Real& U2,
Standard_Real& V2);
static void GLinePoint(const IntPatch_IType typl,
const Handle(IntPatch_GLine)& GLine,
const Standard_Real aT,
gp_Pnt& aP);
static void AdjustPeriodic(const Handle(GeomAdaptor_HSurface)& myHS1,
const Handle(GeomAdaptor_HSurface)& myHS2,
Standard_Real& u1,
Standard_Real& v1,
Standard_Real& u2,
Standard_Real& v2);
static
Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
const IntPatch_IType aType,
const Standard_Real aTol3D);
static void RejectDuplicates(NCollection_Array1<GeomInt_Vertex>& theVtxArr);
//=======================================================================
//function : Perform
//purpose :
@@ -154,7 +142,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
const Standard_Real pmid = (firstp+lastp)*0.5;
const gp_Pnt Pmid = ALine->Value(pmid);
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT) {
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
@@ -181,7 +169,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2);
const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
Pmid.Parameters(u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT) {
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
@@ -194,14 +182,14 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
else {
const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp));
Pfirst.Parameters(u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT) { //-- !=ON donne Pb
TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
if(in2 != TopAbs_OUT) { //-- !=ON
const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp));
Plast.Parameters(u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT) { //-- !=ON donne Pb
in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
@@ -309,7 +297,7 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
GLinePoint(typl, GLine, pmid, Pmid);
//
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT) {
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
@@ -549,26 +537,88 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
done = Standard_True;
}
//=======================================================================
//function : Recadre
//function : TreatCircle
//purpose :
//=======================================================================
void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
const Handle(GeomAdaptor_HSurface)& myHS2,
Standard_Real& u1,
Standard_Real& v1,
Standard_Real& u2,
Standard_Real& v2)
{
Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
void GeomInt_LineConstructor::TreatCircle(const Handle(IntPatch_Line)& theLine,
const Standard_Real theTol)
{
const IntPatch_IType aType = theLine->ArcType();
const Handle(IntPatch_GLine) aGLine(Handle(IntPatch_GLine)::DownCast(theLine));
if (RejectMicroCircle(aGLine, aType, theTol))
{
return;
}
//----------------------------------------
const Standard_Integer aNbVtx = aGLine->NbVertex();
NCollection_Array1<GeomInt_Vertex> aVtxArr(1, aNbVtx + 1);
for (Standard_Integer i = 1; i <= aNbVtx; i++)
{
aVtxArr(i).SetVertex(aGLine->Vertex(i));
}
std::sort(aVtxArr.begin(), aVtxArr.begin() + aNbVtx);
//Create last vertex
const Standard_Real aMinPrm = aVtxArr.First().Getvertex().ParameterOnLine() + TwoPI;
aVtxArr.ChangeLast().SetParameter(aMinPrm);
RejectDuplicates(aVtxArr);
std::sort(aVtxArr.begin(), aVtxArr.end());
Standard_Real aU1, aV1, aU2, aV2;
gp_Pnt aPmid;
gp_Pnt2d aP2D;
for (Standard_Integer i = aVtxArr.Lower(); i <= aVtxArr.Upper() - 1; i++)
{
const Standard_Real aT1 = aVtxArr(i).Getvertex().ParameterOnLine();
const Standard_Real aT2 = aVtxArr(i + 1).Getvertex().ParameterOnLine();
if (aT2 == RealLast())
break;
const Standard_Real aTmid = (aT1 + aT2)*0.5;
GLinePoint(aType, aGLine, aTmid, aPmid);
//
Parameters(myHS1, myHS2, aPmid, aU1, aV1, aU2, aV2);
AdjustPeriodic(myHS1, myHS2, aU1, aV1, aU2, aV2);
//
aP2D.SetCoord(aU1, aV1);
TopAbs_State aState = myDom1->Classify(aP2D, theTol);
if (aState != TopAbs_OUT)
{
aP2D.SetCoord(aU2, aV2);
aState = myDom2->Classify(aP2D, theTol);
if (aState != TopAbs_OUT)
{
seqp.Append(aT1);
seqp.Append(aT2);
}
}
}
}
//=======================================================================
//function : AdjustPeriodic
//purpose :
//=======================================================================
void AdjustPeriodic(const Handle(GeomAdaptor_HSurface)& myHS1,
const Handle(GeomAdaptor_HSurface)& myHS2,
Standard_Real& u1,
Standard_Real& v1,
Standard_Real& u2,
Standard_Real& v2)
{
Standard_Boolean myHS1IsUPeriodic, myHS1IsVPeriodic;
const GeomAbs_SurfaceType typs1 = myHS1->GetType();
switch (typs1)
{
{
case GeomAbs_Cylinder:
case GeomAbs_Cone:
case GeomAbs_Sphere:
{
case GeomAbs_Sphere:
{
myHS1IsUPeriodic = Standard_True;
myHS1IsVPeriodic = Standard_False;
break;
@@ -585,14 +635,14 @@ void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
break;
}
}
Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
Standard_Boolean myHS2IsUPeriodic, myHS2IsVPeriodic;
const GeomAbs_SurfaceType typs2 = myHS2->GetType();
switch (typs2)
{
{
case GeomAbs_Cylinder:
case GeomAbs_Cone:
case GeomAbs_Sphere:
{
case GeomAbs_Sphere:
{
myHS2IsUPeriodic = Standard_True;
myHS2IsVPeriodic = Standard_False;
break;
@@ -611,31 +661,36 @@ void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
}
Standard_Real du, dv;
//
if(myHS1IsUPeriodic) {
const Standard_Real lmf = M_PI+M_PI; //-- myHS1->UPeriod();
if (myHS1IsUPeriodic)
{
const Standard_Real lmf = M_PI + M_PI; //-- myHS1->UPeriod();
const Standard_Real f = myHS1->FirstUParameter();
const Standard_Real l = myHS1->LastUParameter();
GeomInt::AdjustPeriodic(u1, f, l, lmf, u1, du);
}
if(myHS1IsVPeriodic) {
const Standard_Real lmf = M_PI+M_PI; //-- myHS1->VPeriod();
if (myHS1IsVPeriodic)
{
const Standard_Real lmf = M_PI + M_PI; //-- myHS1->VPeriod();
const Standard_Real f = myHS1->FirstVParameter();
const Standard_Real l = myHS1->LastVParameter();
GeomInt::AdjustPeriodic(v1, f, l, lmf, v1, dv);
}
if(myHS2IsUPeriodic) {
const Standard_Real lmf = M_PI+M_PI; //-- myHS2->UPeriod();
if (myHS2IsUPeriodic)
{
const Standard_Real lmf = M_PI + M_PI; //-- myHS2->UPeriod();
const Standard_Real f = myHS2->FirstUParameter();
const Standard_Real l = myHS2->LastUParameter();
GeomInt::AdjustPeriodic(u2, f, l, lmf, u2, du);
}
if(myHS2IsVPeriodic) {
const Standard_Real lmf = M_PI+M_PI; //-- myHS2->VPeriod();
if (myHS2IsVPeriodic)
{
const Standard_Real lmf = M_PI + M_PI; //-- myHS2->VPeriod();
const Standard_Real f = myHS2->FirstVParameter();
const Standard_Real l = myHS2->LastVParameter();
GeomInt::AdjustPeriodic(v2, f, l, lmf, v2, dv);
}
}
//=======================================================================
//function : Parameters
//purpose :
@@ -651,6 +706,7 @@ void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
Parameters(myHS1, Ptref, U1, V1);
Parameters(myHS2, Ptref, U2, V2);
}
//=======================================================================
//function : Parameter
//purpose :
@@ -662,26 +718,27 @@ void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
{
IntSurf_Quadric quad1;
//
switch (myHS1->Surface().GetType()) {
case GeomAbs_Plane:
quad1.SetValue(myHS1->Surface().Plane());
switch (myHS1->Surface().GetType())
{
case GeomAbs_Plane:
quad1.SetValue(myHS1->Surface().Plane());
break;
case GeomAbs_Cylinder:
quad1.SetValue(myHS1->Surface().Cylinder());
case GeomAbs_Cylinder:
quad1.SetValue(myHS1->Surface().Cylinder());
break;
case GeomAbs_Cone:
quad1.SetValue(myHS1->Surface().Cone());
case GeomAbs_Cone:
quad1.SetValue(myHS1->Surface().Cone());
break;
case GeomAbs_Sphere:
quad1.SetValue(myHS1->Surface().Sphere());
case GeomAbs_Sphere:
quad1.SetValue(myHS1->Surface().Sphere());
break;
case GeomAbs_Torus:
quad1.SetValue(myHS1->Surface().Torus());
quad1.SetValue(myHS1->Surface().Torus());
break;
default:
default:
throw Standard_ConstructionError("GeomInt_LineConstructor::Parameters");
}
quad1.Parameters(Ptref,U1,V1);
quad1.Parameters(Ptref, U1, V1);
}
//=======================================================================
@@ -693,238 +750,28 @@ void GLinePoint(const IntPatch_IType typl,
const Standard_Real aT,
gp_Pnt& aP)
{
switch (typl) {
case IntPatch_Lin:
aP = ElCLib::Value(aT, GLine->Line());
break;
case IntPatch_Circle:
aP = ElCLib::Value(aT, GLine->Circle());
break;
case IntPatch_Ellipse:
aP = ElCLib::Value(aT, GLine->Ellipse());
break;
case IntPatch_Hyperbola:
aP = ElCLib::Value(aT, GLine->Hyperbola());
break;
case IntPatch_Parabola:
aP = ElCLib::Value(aT, GLine->Parabola());
break;
default:
throw Standard_ConstructionError("GeomInt_LineConstructor::Parameters");
switch (typl)
{
case IntPatch_Lin:
aP = ElCLib::Value(aT, GLine->Line());
break;
case IntPatch_Circle:
aP = ElCLib::Value(aT, GLine->Circle());
break;
case IntPatch_Ellipse:
aP = ElCLib::Value(aT, GLine->Ellipse());
break;
case IntPatch_Hyperbola:
aP = ElCLib::Value(aT, GLine->Hyperbola());
break;
case IntPatch_Parabola:
aP = ElCLib::Value(aT, GLine->Parabola());
break;
default:
throw Standard_ConstructionError("GeomInt_LineConstructor::Parameters");
}
}
//=======================================================================
//function : TreatCircle
//purpose :
//=======================================================================
void GeomInt_LineConstructor::TreatCircle(const Handle(IntPatch_Line)& aLine,
const Standard_Real aTol)
{
Standard_Boolean bRejected;
IntPatch_IType aType;
//
aType=aLine->ArcType();
Handle(IntPatch_GLine) aGLine (Handle(IntPatch_GLine)::DownCast (aLine));
//
bRejected=RejectMicroCircle(aGLine, aType, aTol);
if (bRejected) {
return;
}
//----------------------------------------
Standard_Boolean bFound;
Standard_Integer aNbVtx, aNbVtxWas, i;
Standard_Real aTolPC, aT, aT1, aT2, aTmid, aTwoPI, aTolPC1;
Standard_Real aU1, aV1, aU2, aV2;
TopAbs_State aIn1, aIn2;
GeomAbs_SurfaceType aTS1, aTS2;
gp_Pnt aPmid;
gp_Pnt2d aP2D;
GeomInt_RealWithFlag *pVtx;
//-------------------------------------1
aTwoPI=M_PI+M_PI;
aTolPC=Precision::PConfusion();
aNbVtxWas=GeomInt_LineTool::NbVertex(aLine);
aNbVtx=aNbVtxWas+2;
//-------------------------------------2
aTS1=myHS1->GetType();
aTS2=myHS2->GetType();
//
// About the value aTolPC1=1000.*aTolPC,
// see IntPatch_GLine.cxx, line:398
// for more details;
aTolPC1=1000.*aTolPC;
//-------------------------------------
//
pVtx=new GeomInt_RealWithFlag [aNbVtx];
//
pVtx[0].SetValue(0.);
pVtx[1].SetValue(aTwoPI);
//
for(i=1; i<=aNbVtxWas; ++i) {
aT=GeomInt_LineTool::Vertex(aLine, i).ParameterOnLine();
aT=AdjustOnPeriod(aT, aTwoPI);
pVtx[i+1].SetValue(aT);
}
//
SortShell(aNbVtx, pVtx);
//
RejectNearBeacons(aNbVtx, pVtx, aTolPC1, aTS1, aTS2);
//
RejectDuplicates(aNbVtx, pVtx, aTolPC);
//
if ((aType==IntPatch_Circle || aType==IntPatch_Ellipse)&& aNbVtx>2) { // zz
bFound=Standard_False;
for(i=1; i<=aNbVtxWas; ++i) {
aT=GeomInt_LineTool::Vertex(aLine, i).ParameterOnLine();
if (fabs(aT) < aTolPC1 || fabs(aT-aTwoPI) < aTolPC1) {
bFound=!bFound;
break;
}
}
if (!bFound) {
aT=pVtx[1].Value()+aTwoPI;
pVtx[aNbVtx-1].SetValue(aT);
//
for(i=0; i<aNbVtx - 1; ++i) {
aT=pVtx[i+1].Value();
pVtx[i].SetValue(aT);
}
--aNbVtx;
}
}
//
for(i=0; i<aNbVtx-1; ++i) {
aT1=pVtx[i].Value();
aT2=pVtx[i+1].Value();
aTmid=(aT1+aT2)*0.5;
GLinePoint(aType, aGLine, aTmid, aPmid);
//
Parameters(myHS1, myHS2, aPmid, aU1, aV1, aU2, aV2);
Recadre(myHS1, myHS2, aU1, aV1, aU2, aV2);
//
aP2D.SetCoord(aU1, aV1);
aIn1=myDom1->Classify(aP2D, aTol);
if(aIn1 != TopAbs_OUT) {
aP2D.SetCoord(aU2, aV2);
aIn2=myDom2->Classify(aP2D, aTol);
if(aIn2 != TopAbs_OUT) {
seqp.Append(aT1);
seqp.Append(aT2);
}
}
}
//
delete [] pVtx;
}
//=======================================================================
//function : RejectNearBeacons
//purpose : Reject the thickenings near the beacon points (if exist)
// The gifts, made by sweep algo.
// chl/930/B5 B8 C2 C5 E2 E5 E8 F2 G8 H2 H5 H8
//=======================================================================
void RejectNearBeacons(Standard_Integer& aNbVtx,
GeomInt_RealWithFlag *pVtx,
Standard_Real aTolPC1,
const GeomAbs_SurfaceType aTS1,
const GeomAbs_SurfaceType aTS2)
{
Standard_Integer i, j, iBcn;
Standard_Real aT, aBcn[2];
//
if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
aBcn[0]=0.5*M_PI;
aBcn[1]=1.5*M_PI;
//
for (j=0; j<2; ++j) {
iBcn=-1;
for(i=0; i<aNbVtx; ++i) {
aT=pVtx[i].Value();
if (aT==aBcn[j]) {
iBcn=i;
break;
}
}
//
if (iBcn<0) {
// The beacon is not found
continue;
}
//
for(i=0; i<aNbVtx; ++i) {
if (i!=iBcn) {
aT=pVtx[i].Value();
if (fabs(aT-aBcn[j]) < aTolPC1) {
pVtx[i].SetFlag(0);
}
}
}
}// for (j=0; j<2; ++j) {
//------------------------------------------
j=0;
for(i=0; i<aNbVtx; ++i) {
if (pVtx[i].Flag()) {
pVtx[j]=pVtx[i];
++j;
}
}
aNbVtx=j;
}// if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
}
//=======================================================================
//function : RejectDuplicates
//purpose :
//=======================================================================
void RejectDuplicates(Standard_Integer& aNbVtx,
GeomInt_RealWithFlag *pVtx,
Standard_Real aTolPC)
{
Standard_Integer i, j;
Standard_Real dX, aT1, aT2;
//
for(i=0; i<aNbVtx-1; ++i) {
aT2=pVtx[i+1].Value();
aT1=pVtx[i].Value();
dX=aT2-aT1;
if (dX<aTolPC) {
pVtx[i+1].SetFlag(0);
}
}
//
j=0;
for(i=0; i<aNbVtx; ++i) {
if (pVtx[i].Flag()) {
pVtx[j]=pVtx[i];
++j;
}
}
aNbVtx=j;
}
//=======================================================================
//function : AdjustOnPeriod
//purpose :
//=======================================================================
Standard_Real AdjustOnPeriod(const Standard_Real aTr,
const Standard_Real aPeriod)
{
Standard_Integer k;
Standard_Real aT;
//
aT=aTr;
if (aT<0.) {
k=-(Standard_Integer)(aT/aPeriod)+1;
aT=aT+k*aPeriod;
}
//
if (!(aT>=0. && aT<=aPeriod)) {
k=(Standard_Integer)(aT/aPeriod);
aT=aT-k*aPeriod;
}
//
return aT;
}
//=======================================================================
//function : RejectMicroCrcles
//purpose :
@@ -948,35 +795,67 @@ Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
}
return bRet;
}
//=======================================================================
// function: SortShell
// purpose :
//function : RejectDuplicates
//purpose : Finds two coincident IntPatch_Points (if they exist) and
// sets Parameter-On-Line fore one such point to DBL_MAX
// (i.e. its use in the future is forbidden).
//
//ATTENTION!!!
// The source array must be sorted in ascending order.
//=======================================================================
void SortShell(const Standard_Integer n,
GeomInt_RealWithFlag *a)
void RejectDuplicates(NCollection_Array1<GeomInt_Vertex>& theVtxArr)
{
Standard_Integer nd, i, j, l, d=1;
GeomInt_RealWithFlag x;
//
while(d<=n) {
d*=2;
// About the value aTolPC=1000.*Precision::PConfusion(),
// see IntPatch_GLine::ComputeVertexParameters(...)
// for more details;
const Standard_Real aTolPC = 1000.*Precision::PConfusion();
//Find duplicates in a slice of the array [LowerBound, UpperBound-1].
//If a duplicate has been found, the element with greater index will be rejected.
for (Standard_Integer i = theVtxArr.Lower(); i <= theVtxArr.Upper() - 2; i++)
{
const IntPatch_Point &aVi = theVtxArr(i).Getvertex();
const Standard_Real aPrmi = aVi.ParameterOnLine();
if (aPrmi == RealLast())
continue;
for (Standard_Integer j = i + 1; j <= theVtxArr.Upper() - 1; j++)
{
const IntPatch_Point &aVj = theVtxArr(j).Getvertex();
const Standard_Real aPrmj = aVj.ParameterOnLine();
if (aPrmj - aPrmi < aTolPC)
{
theVtxArr(j).SetParameter(RealLast());
}
else
{
break;
}
}
}
//Find duplicates with the last element of the array.
//If a duplicate has been found, the found element will be rejected.
const Standard_Real aMaxPrm = theVtxArr.Last().Getvertex().ParameterOnLine();
for (Standard_Integer i = theVtxArr.Upper() - 1; i > theVtxArr.Lower(); i--)
{
const IntPatch_Point &aVi = theVtxArr(i).Getvertex();
const Standard_Real aPrmi = aVi.ParameterOnLine();
if (aPrmi == RealLast())
continue;
if ((aMaxPrm - aPrmi) < aTolPC)
{
theVtxArr(i).SetParameter(RealLast());
}
else
{
break;
}
}
//
while (d) {
d=(d-1)/2;
//
nd=n-d;
for (i=0; i<nd; ++i) {
j=i;
m30:;
l=j+d;
if (a[l] < a[j]){
x=a[j];
a[j]=a[l];
a[l]=x;
j-=d;
if (j > -1) goto m30;
}//if (a[l] < a[j]){
}//for (i=0; i<nd; ++i)
}//while (1)
}

View File

@@ -34,10 +34,15 @@ void GeometryTest::AllCommands(Draw_Interpretor& theCommands)
GeometryTest::FairCurveCommands(theCommands);
GeometryTest::SurfaceCommands(theCommands);
GeometryTest::ConstraintCommands(theCommands);
// See bug #0030366
// GeometryTest::API2dCommands(theCommands);
GeometryTest::APICommands(theCommands);
GeometryTest::ContinuityCommands(theCommands);
GeometryTest::TestProjCommands(theCommands);
GeometryTest::PolyCommands(theCommands);
// define the TCL variable Draw_GEOMETRY
//char* com = "set Draw_GEOMETRY 1";
//theCommands.Eval(com);

View File

@@ -21,6 +21,7 @@
#include <DrawTrSurf_Polygon3D.hxx>
#include <DrawTrSurf_Triangulation.hxx>
#include <GeometryTest.hxx>
#include <Poly.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <Poly_Polygon2D.hxx>
#include <Poly_Polygon3D.hxx>
@@ -183,6 +184,108 @@ static Standard_Integer shtriangles(Draw_Interpretor& , Standard_Integer n, cons
return 0;//wnt
}
//=======================================================================
//function : AddNode
//purpose :
//=======================================================================
template <typename Poly, typename Point, typename PointArr>
static inline void AddNode(const Handle(Poly)& thePolygon,
const Point& thePnt,
PointArr& theNodes)
{
for (Standard_Integer i = thePolygon->Nodes().Lower();
i <= thePolygon->Nodes().Upper(); i++)
{
theNodes[i] = thePolygon->Nodes()[i];
}
theNodes.ChangeLast() = thePnt;
}
//=======================================================================
//function : AddNode
//purpose :
//=======================================================================
static Standard_Integer AddNode(Draw_Interpretor& theDI,
Standard_Integer theNArg,
const char** theArgVal)
{
if (theNArg < 4)
{
theDI << "Not enough arguments\n";
return 1;
}
if (theNArg == 4)
{
Handle(Poly_Polygon2D) aPoly2d = DrawTrSurf::GetPolygon2D(theArgVal[1]);
TColgp_Array1OfPnt2d aNodes(aPoly2d->Nodes().Lower(),
aPoly2d->Nodes().Upper() + 1);
AddNode(aPoly2d, gp_Pnt2d(Draw::Atof(theArgVal[2]),
Draw::Atof(theArgVal[3])), aNodes);
aPoly2d.Nullify();
aPoly2d = new Poly_Polygon2D(aNodes);
DrawTrSurf::Set(theArgVal[1], aPoly2d);
}
else
{
Handle(Poly_Polygon3D) aPoly3d = DrawTrSurf::GetPolygon3D(theArgVal[1]);
TColgp_Array1OfPnt aNodes(aPoly3d->Nodes().Lower(),
aPoly3d->Nodes().Upper() + 1);
AddNode(aPoly3d, gp_Pnt(Draw::Atof(theArgVal[2]),
Draw::Atof(theArgVal[3]),
Draw::Atof(theArgVal[4])), aNodes);
aPoly3d.Nullify();
aPoly3d = new Poly_Polygon3D(aNodes);
DrawTrSurf::Set(theArgVal[1], aPoly3d);
}
return 0;
}
//=======================================================================
//function : PolygonProps
//purpose :
//=======================================================================
static Standard_Integer PolygonProps(Draw_Interpretor& theDI,
Standard_Integer theNArg,
const char** theArgVal)
{
if (theNArg < 2)
{
theDI << "Use: polygonprops polygon2d [-area val] [-perimeter val]\n";
return 1;
}
Handle(Poly_Polygon2D) aPoly2d = DrawTrSurf::GetPolygon2D(theArgVal[1]);
Standard_Real anArea = 0.0, aPerimeter = 0.0;
Poly::PolygonProperties(aPoly2d->Nodes(), anArea, aPerimeter);
theDI << "Area = " << anArea << "\n";
theDI << "Perimeter = " << aPerimeter << "\n";
for (Standard_Integer i = 2; i < theNArg; i++)
{
if (!strcmp(theArgVal[i], "-area"))
{
Draw::Set(theArgVal[++i], anArea);
continue;
}
if (!strcmp(theArgVal[i], "-perimeter"))
{
Draw::Set(theArgVal[++i], aPerimeter);
continue;
}
theDI << "Error: Wrong option: \"" << theArgVal[i] << "\"\n";
break;
}
return 0;
}
//=======================================================================
//function : PolyCommands
//purpose :
@@ -196,6 +299,10 @@ void GeometryTest::PolyCommands(Draw_Interpretor& theCommands)
theCommands.Add("polytr","polytr name nbnodes nbtri x1 y1 z1 ... n1 n2 n3 ...",__FILE__,polytr,g);
theCommands.Add("polygon3d","polygon3d name nbnodes x1 y1 z1 ...",__FILE__,polygon3d,g);
theCommands.Add("polygon2d","polygon2d name nbnodes x1 y1 ...",__FILE__,polygon2d,g);
theCommands.Add("addpolygonnode","addpolygonnode polygon3d(2d) x y [z]",__FILE__, AddNode,g);
theCommands.Add("polygonprops","Computes area and perimeter of 2D-polygon. "
"Run \"polygonprops\" w/o any arguments to read help.\n",
__FILE__, PolygonProps,g);
theCommands.Add("shnodes","shnodes name", __FILE__,shnodes, g);
theCommands.Add("shtriangles","shtriangles name", __FILE__,shtriangles, g);
}

View File

@@ -37,6 +37,8 @@
//-- pas etre mene a bien.
//----------------------------------------------------------------------
#include <algorithm>
#include <ElSLib.hxx>
#include <gp_Cone.hxx>
#include <gp_Cylinder.hxx>
@@ -52,7 +54,7 @@
//function : IntAna_Curve
//purpose :
//=======================================================================
IntAna_Curve::IntAna_Curve()
IntAna_Curve::IntAna_Curve()
{
typequadric=GeomAbs_OtherSurface;
firstbounded=Standard_False;
@@ -62,22 +64,22 @@
//function : SetConeQuadValues
//purpose : Description de l intersection Cone Quadrique
//=======================================================================
void IntAna_Curve::SetConeQuadValues(const gp_Cone& Cone,
const Standard_Real Qxx,
const Standard_Real Qyy,
const Standard_Real Qzz,
const Standard_Real Qxy,
const Standard_Real Qxz,
const Standard_Real Qyz,
const Standard_Real Qx,
const Standard_Real Qy,
const Standard_Real Qz,
const Standard_Real Q1,
const Standard_Real TOL,
const Standard_Real DomInf,
const Standard_Real DomSup,
const Standard_Boolean twocurves,
const Standard_Boolean takezpositive)
void IntAna_Curve::SetConeQuadValues(const gp_Cone& Cone,
const Standard_Real Qxx,
const Standard_Real Qyy,
const Standard_Real Qzz,
const Standard_Real Qxy,
const Standard_Real Qxz,
const Standard_Real Qyz,
const Standard_Real Qx,
const Standard_Real Qy,
const Standard_Real Qz,
const Standard_Real Q1,
const Standard_Real TOL,
const Standard_Real DomInf,
const Standard_Real DomSup,
const Standard_Boolean twocurves,
const Standard_Boolean takezpositive)
{
Ax3 = Cone.Position();
@@ -112,36 +114,40 @@
Z2Cos = (UnSurTgAngle+UnSurTgAngle)*Qxz;
Z2CosCos = Qxx;
Z2SinSin = Qyy;
Z2CosSin = Qxy+Qxy;
Z2CosSin = Qxy;
Tolerance = TOL;
DomainInf = DomInf;
DomainSup = DomSup;
DomainInf = DomInf;
DomainSup = DomSup;
RestrictedInf = RestrictedSup = Standard_True; //-- Le Domaine est Borne
firstbounded = lastbounded = Standard_False;
myFirstParameter = DomainInf;
myLastParameter = (TwoCurves) ? DomainSup + DomainSup - DomainInf :
DomainSup;
}
//=======================================================================
//function : SetCylinderQuadValues
//purpose : Description de l intersection Cylindre Quadrique
//=======================================================================
void IntAna_Curve::SetCylinderQuadValues(const gp_Cylinder& Cyl,
const Standard_Real Qxx,
const Standard_Real Qyy,
const Standard_Real Qzz,
const Standard_Real Qxy,
const Standard_Real Qxz,
const Standard_Real Qyz,
const Standard_Real Qx,
const Standard_Real Qy,
const Standard_Real Qz,
const Standard_Real Q1,
const Standard_Real TOL,
const Standard_Real DomInf,
const Standard_Real DomSup,
const Standard_Boolean twocurves,
const Standard_Boolean takezpositive)
void IntAna_Curve::SetCylinderQuadValues(const gp_Cylinder& Cyl,
const Standard_Real Qxx,
const Standard_Real Qyy,
const Standard_Real Qzz,
const Standard_Real Qxy,
const Standard_Real Qxz,
const Standard_Real Qyz,
const Standard_Real Qx,
const Standard_Real Qy,
const Standard_Real Qz,
const Standard_Real Q1,
const Standard_Real TOL,
const Standard_Real DomInf,
const Standard_Real DomSup,
const Standard_Boolean twocurves,
const Standard_Boolean takezpositive)
{
Ax3 = Cyl.Position();
@@ -157,7 +163,7 @@
Z0Cos = RCylmul2*Qx;
Z0CosCos = Qxx*RCyl*RCyl;
Z0SinSin = Qyy*RCyl*RCyl;
Z0CosSin = RCylmul2*RCyl*Qxy;
Z0CosSin = RCyl*RCyl*Qxy;
Z1Cte = Qz+Qz;
Z1Sin = RCylmul2*Qyz;
@@ -174,18 +180,22 @@
Z2CosSin = 0.0;
Tolerance = TOL;
DomainInf = DomInf;
DomainSup = DomSup;
DomainInf = DomInf;
DomainSup = DomSup;
RestrictedInf = RestrictedSup = Standard_True;
firstbounded = lastbounded = Standard_False;
myFirstParameter = DomainInf;
myLastParameter = (TwoCurves) ? DomainSup + DomainSup - DomainInf :
DomainSup;
}
//=======================================================================
//function : IsOpen
//purpose :
//=======================================================================
Standard_Boolean IntAna_Curve::IsOpen() const
Standard_Boolean IntAna_Curve::IsOpen() const
{
return(RestrictedInf && RestrictedSup);
}
@@ -194,17 +204,16 @@
//function : Domain
//purpose :
//=======================================================================
void IntAna_Curve::Domain(Standard_Real& DInf,
Standard_Real& DSup) const
void IntAna_Curve::Domain(Standard_Real& theFirst,
Standard_Real& theLast) const
{
if(RestrictedInf && RestrictedSup) {
DInf=DomainInf;
DSup=DomainSup;
if(TwoCurves) {
DSup+=DSup-DInf;
}
if (RestrictedInf && RestrictedSup)
{
theFirst = myFirstParameter;
theLast = myLastParameter;
}
else {
else
{
throw Standard_DomainError("IntAna_Curve::Domain");
}
}
@@ -212,7 +221,7 @@
//function : IsConstant
//purpose :
//=======================================================================
Standard_Boolean IntAna_Curve::IsConstant() const
Standard_Boolean IntAna_Curve::IsConstant() const
{
//-- ??? Pas facile de decider a la seule vue des Param.
return(Standard_False);
@@ -222,7 +231,7 @@
//function : IsFirstOpen
//purpose :
//=======================================================================
Standard_Boolean IntAna_Curve::IsFirstOpen() const
Standard_Boolean IntAna_Curve::IsFirstOpen() const
{
return(firstbounded);
}
@@ -231,7 +240,7 @@
//function : IsLastOpen
//purpose :
//=======================================================================
Standard_Boolean IntAna_Curve::IsLastOpen() const
Standard_Boolean IntAna_Curve::IsLastOpen() const
{
return(lastbounded);
}
@@ -239,7 +248,7 @@
//function : SetIsFirstOpen
//purpose :
//=======================================================================
void IntAna_Curve::SetIsFirstOpen(const Standard_Boolean Flag)
void IntAna_Curve::SetIsFirstOpen(const Standard_Boolean Flag)
{
firstbounded = Flag;
}
@@ -248,7 +257,7 @@
//function : SetIsLastOpen
//purpose :
//=======================================================================
void IntAna_Curve::SetIsLastOpen(const Standard_Boolean Flag)
void IntAna_Curve::SetIsLastOpen(const Standard_Boolean Flag)
{
lastbounded = Flag;
}
@@ -257,29 +266,40 @@
//function : InternalUVValue
//purpose :
//=======================================================================
void IntAna_Curve::InternalUVValue(const Standard_Real theta,
Standard_Real& Param1,
Standard_Real& Param2,
Standard_Real& A,
Standard_Real& B,
Standard_Real& C,
Standard_Real& cost,
Standard_Real& sint,
Standard_Real& SigneSqrtDis) const
void IntAna_Curve::InternalUVValue(const Standard_Real theta,
Standard_Real& Param1,
Standard_Real& Param2,
Standard_Real& A,
Standard_Real& B,
Standard_Real& C,
Standard_Real& cost,
Standard_Real& sint,
Standard_Real& SigneSqrtDis) const
{
const Standard_Real aRelTolp = 1.0+Epsilon(1.0), aRelTolm = 1.0-Epsilon(1.0);
// Infinitesimal step of increasing curve parameter. See comment below.
const Standard_Real aDT = 100.0*Epsilon(DomainSup + DomainSup - DomainInf);
Standard_Real Theta=theta;
Standard_Boolean SecondSolution=Standard_False;
if((Theta<DomainInf*aRelTolm) ||
((Theta>DomainSup*aRelTolp) && (!TwoCurves)) ||
(Theta>(DomainSup+DomainSup-DomainInf)*aRelTolp)) {
if ((Theta<DomainInf*aRelTolm) ||
((Theta>DomainSup*aRelTolp) && (!TwoCurves)) ||
(Theta>(DomainSup + DomainSup - DomainInf)*aRelTolp))
{
SigneSqrtDis = 0.;
throw Standard_DomainError("IntAna_Curve::Domain");
}
if(Theta>DomainSup) {
Theta=DomainSup+DomainSup-Theta;
if (Abs(Theta - DomainSup) < aDT)
{
// Point of Null-discriminant.
Theta = DomainSup;
}
else if (Theta>DomainSup)
{
Theta = DomainSup + DomainSup - Theta;
SecondSolution=Standard_True;
}
@@ -291,53 +311,56 @@
//
cost = Cos(Theta);
sint = Sin(Theta);
Standard_Real costsint = cost*sint;
const Standard_Real aSin2t = Sin(Theta + Theta);
const Standard_Real aCos2t = Cos(Theta + Theta);
A=Z2Cte+sint*(Z2Sin+sint*Z2SinSin)+cost*(Z2Cos+cost*Z2CosCos)
+Z2CosSin*costsint;
+ Z2CosSin*aSin2t;
const Standard_Real aDA = cost*Z2Sin - sint*Z2Cos +
aSin2t*(Z2SinSin - Z2CosCos) +
aCos2t*(Z2CosSin * Z2CosSin);
B=Z1Cte+sint*(Z1Sin+sint*Z1SinSin)+cost*(Z1Cos+cost*Z1CosCos)
+Z1CosSin*costsint;
+ Z1CosSin*aSin2t;
const Standard_Real aDB = Z1Sin*cost - Z1Cos*sint +
aSin2t*(Z1SinSin - Z1CosCos) +
aCos2t*(Z1CosSin + Z1CosSin);
C=Z0Cte+sint*(Z0Sin+sint*Z0SinSin)+cost*(Z0Cos+cost*Z0CosCos)
+Z0CosSin*costsint;
+ Z0CosSin*aSin2t;
const Standard_Real aDC = Z0Sin*cost - Z0Cos*sint +
aSin2t*(Z0SinSin - Z0CosCos) +
aCos2t*(Z0CosSin + Z0CosSin);
const Standard_Real aDiscriminant = Max(B*B-4.0*A*C, 0.0);
Standard_Real aDiscriminant = B*B-4.0*A*C;
// We consider that infinitesimal dt = aDT.
// Error of discriminant computation is equal to
// (d(Disc)/dt)*dt, where 1st derivative d(Disc)/dt = 2*B*aDB - 4*(A*aDC + C*aDA).
const Standard_Real aTolD = 2.0*aDT*Abs(B*aDB - 2.0*(A*aDC + C*aDA));
if(Abs(A)<=Precision::PConfusion()) {
//-- cout<<" IntAna_Curve:: Internal UV Value : A="<<A<<" -> Abs(A)="<<Abs(A)<<endl;
if(Abs(B)<=Precision::PConfusion()) {
//-- cout<<" Probleme : Pas de solutions "<<endl;
Param2=0.0;
if (aDiscriminant < aTolD)
aDiscriminant = 0.0;
if (Abs(A) <= Precision::PConfusion())
{
if (Abs(B) <= Precision::PConfusion())
{
Param2 = 0.0;
}
else {
//modified by NIZNHY-PKV Fri Dec 2 16:02:46 2005f
Param2 = -C/B;
/*
if(!SecondSolution) {
//-- Cas Param2 = (-B+Sqrt(Discriminant))/(A+A);
//-- = (-B+Sqrt(B**2 - Eps)) / 2A
//-- = -C / B
Param2 = -C/B;
}
else {
//-- Cas Param2 = (-B-Sqrt(Discriminant))/(A+A);
//-- = (-B-Sqrt(B**2 - Eps)) / 2A
if(A) {
Param2 = -B/A;
}
else {
Param2 = -B*10000000.0;
}
}
*/
//modified by NIZNHY-PKV Fri Dec 2 16:02:54 2005t
else
{
Param2 = -C / B;
}
}
else {
SigneSqrtDis = (SecondSolution)? Sqrt(aDiscriminant) : -Sqrt(aDiscriminant);
Param2=(-B+SigneSqrtDis)/(A+A);
else
{
SigneSqrtDis = (SecondSolution) ? Sqrt(aDiscriminant) : -Sqrt(aDiscriminant);
Param2 = (-B + SigneSqrtDis) / (A + A);
}
}
@@ -345,7 +368,7 @@
//function : Value
//purpose :
//=======================================================================
gp_Pnt IntAna_Curve::Value(const Standard_Real theta)
gp_Pnt IntAna_Curve::Value(const Standard_Real theta)
{
Standard_Real A, B, C, U, V, sint, cost, SigneSqrtDis;
//
@@ -361,9 +384,9 @@
//function : D1u
//purpose :
//=======================================================================
Standard_Boolean IntAna_Curve::D1u(const Standard_Real theta,
gp_Pnt& Pt,
gp_Vec& Vec)
Standard_Boolean IntAna_Curve::D1u(const Standard_Real theta,
gp_Pnt& Pt,
gp_Vec& Vec)
{
//-- Pour detecter le cas ou le calcul est impossible
Standard_Real A, B, C, U, V, sint, cost, SigneSqrtDis;
@@ -374,14 +397,15 @@
InternalUVValue(theta,U,V,A,B,C,cost,sint,SigneSqrtDis);
//
Pt = Value(theta);
if(Abs(A)<0.0000001 || Abs(SigneSqrtDis)<0.0000000001) return(Standard_False);
if (Abs(A)<1.0e-7 || Abs(SigneSqrtDis)<1.0e-10) return(Standard_False);
//-- Approximation de la derivee (mieux que le calcul mathematique!)
Standard_Real dtheta = (DomainSup-DomainInf)*0.000001;
Standard_Real dtheta = (DomainSup - DomainInf)*1.0e-6;
Standard_Real theta2 = theta+dtheta;
if((theta2<DomainInf) || ((theta2>DomainSup) && (!TwoCurves))
|| (theta2>(DomainSup+DomainSup-DomainInf+0.00000000000001))) {
if ((theta2<DomainInf) || ((theta2>DomainSup) && (!TwoCurves))
|| (theta2>(DomainSup + DomainSup - DomainInf + 1.0e-14)))
{
dtheta = -dtheta;
theta2 = theta+dtheta;
}
@@ -395,147 +419,93 @@
}
//=======================================================================
//function : FindParameter
//purpose : Para est en sortie le parametre sur la courbe
//purpose : Projects P to the ALine. Returns the list of parameters as a results
// of projection.
// Sometimes aline can be self-intersected line (see bug #29807 where
// ALine goes through the cone apex).
//=======================================================================
Standard_Boolean IntAna_Curve::FindParameter (const gp_Pnt& P,
Standard_Real& Para) const
void IntAna_Curve::FindParameter(const gp_Pnt& theP,
TColStd_ListOfReal& theParams) const
{
Standard_Real theta,z, aTolPrecision=0.0001;
Standard_Real PIpPI = M_PI + M_PI;
const Standard_Real aPIpPI = M_PI + M_PI,
anEpsAng = 1.e-8,
aSqTolPrecision=1.0e-8;
Standard_Real aTheta = 0.0;
//
switch (typequadric) {
case GeomAbs_Cylinder:
switch (typequadric)
{
case GeomAbs_Cylinder:
{
ElSLib::CylinderParameters(Ax3,RCyl,P,theta,z);
Standard_Real aZ;
ElSLib::CylinderParameters(Ax3, RCyl, theP, aTheta, aZ);
}
break;
case GeomAbs_Cone:
{
Standard_Real aZ;
ElSLib::ConeParameters(Ax3, RCyl, Angle, theP, aTheta, aZ);
}
break;
default:
return;
}
//
if (!firstbounded && (DomainInf > aTheta) && ((DomainInf - aTheta) <= anEpsAng))
{
aTheta = DomainInf;
}
else if (!lastbounded && (aTheta > DomainSup) && ((aTheta - DomainSup) <= anEpsAng))
{
aTheta = DomainSup;
}
//
if (aTheta < DomainInf)
{
aTheta = aTheta + aPIpPI;
}
else if (aTheta > DomainSup)
{
aTheta = aTheta - aPIpPI;
}
const Standard_Integer aMaxPar = 5;
Standard_Real aParams[aMaxPar] = {DomainInf, DomainSup, aTheta,
(TwoCurves)? DomainSup + DomainSup - aTheta : RealLast(),
(TwoCurves) ? DomainSup + DomainSup - DomainInf : RealLast()};
std::sort(aParams, aParams + aMaxPar - 1);
for (Standard_Integer i = 0; i < aMaxPar; i++)
{
if (aParams[i] > myLastParameter)
break;
case GeomAbs_Cone :
if (aParams[i] < myFirstParameter)
continue;
if (i && (aParams[i] - aParams[i - 1]) < Precision::PConfusion())
continue;
Standard_Real U = 0.0, V= 0.0,
A = 0.0, B = 0.0, C = 0.0,
sint = 0.0, cost = 0.0, SigneSqrtDis = 0.0;
InternalUVValue(aParams[i], U, V, A, B, C,
cost, sint, SigneSqrtDis);
const gp_Pnt aP(InternalValue(U, V));
if (aP.SquareDistance(theP) < aSqTolPrecision)
{
ElSLib::ConeParameters(Ax3,RCyl,Angle,P,theta,z);
}
break;
default:
return Standard_False;
break;
}
//
Standard_Real epsAng = 1.e-8;
Standard_Real tmin = DomainInf;
Standard_Real tmax = DomainSup;
Standard_Real U,V,A,B,C,sint,cost,SigneSqrtDis;
Standard_Real z1,z2;
A=0.0; B=0.0; C=0.0;
U=0.0; V=0.0;
sint=0.0; cost=0.0;
SigneSqrtDis=0.0;
//U=V=A=B=C=sint=cost=SigneSqrtDis=0.0;
//
if (!firstbounded && tmin > theta && (tmin-theta) <= epsAng) {
theta = tmin;
}
else if (!lastbounded && theta > tmax && (theta-tmax) <= epsAng) {
theta = tmax;
}
//
if (theta < tmin ) {
theta = theta + PIpPI;
}
else if (theta > tmax) {
theta = theta - PIpPI;
}
if (theta < tmin || theta > tmax) {
if(theta>tmax) {
InternalUVValue(tmax,U,V,A,B,C,cost,sint,SigneSqrtDis);
gp_Pnt PMax(InternalValue(U,V));
if(PMax.Distance(P) < aTolPrecision) {
Para = tmax;
return(Standard_True);
}
}
if(theta<tmin) {
InternalUVValue(tmin,U,V,A,B,C,cost,sint,SigneSqrtDis);
gp_Pnt PMin(InternalValue(U,V));
if(PMin.Distance(P) < aTolPrecision) {
Para = tmin;
return(Standard_True);
}
}
//-- lbr le 14 Fev 96 : On teste malgre tout si le point n est pas le
//-- point de debut ou de fin
//-- cout<<"False 1 "<<endl;
// theta = tmin; le 25 Nov 96
}
if (TwoCurves) {
if(theta > tmax)
theta = tmax;
if(theta < tmin)
theta = tmin;
InternalUVValue(theta,U,z1,A,B,C,cost,sint,SigneSqrtDis);
A = B = C = sint = cost = SigneSqrtDis = 0.0;
InternalUVValue(tmax+tmax - theta,U,z2,A,B,C,cost,sint,SigneSqrtDis);
if (Abs(z-z1) <= Abs(z-z2)) {
Para = theta;
}
else {
Para = tmax+tmax - theta;
theParams.Append(aParams[i]);
}
}
else {
Para = theta;
}
if((Para<DomainInf) || ((Para>DomainSup) && (!TwoCurves))
|| (Para>(DomainSup+DomainSup-DomainInf+0.00000000000001))) {
return(Standard_False);
}
InternalUVValue(Para,U,V,A,B,C,cost,sint,SigneSqrtDis);
gp_Pnt PPara = InternalValue(U,V);
Standard_Real Dist = PPara.Distance(P);
if(Dist > aTolPrecision) {
//-- Il y a eu un probleme
//-- On teste si le point est un point double
InternalUVValue(tmin,U,V,A,B,C,cost,sint,SigneSqrtDis);
PPara = InternalValue(U,V);
Dist = PPara.Distance(P);
if(Dist <= aTolPrecision) {
Para = tmin;
return(Standard_True);
}
InternalUVValue(tmax,U,V,A,B,C,cost,sint,SigneSqrtDis);
PPara = InternalValue(U,V);
Dist = PPara.Distance(P);
if(Dist <= aTolPrecision) {
Para = tmax;
return(Standard_True);
}
if (TwoCurves) {
Standard_Real Theta = DomainSup+DomainSup-DomainInf;
InternalUVValue(Theta,U,V,A,B,C,cost,sint,SigneSqrtDis);
PPara = InternalValue(U,V);
Dist = PPara.Distance(P);
if(Dist <= aTolPrecision) {
Para = Theta;
return(Standard_True);
}
}
return(Standard_False);
}
return(Standard_True);
}
//=======================================================================
//function : InternalValue
//purpose :
//=======================================================================
gp_Pnt IntAna_Curve::InternalValue(const Standard_Real U,
const Standard_Real _V) const
gp_Pnt IntAna_Curve::InternalValue(const Standard_Real U,
const Standard_Real _V) const
{
//-- cout<<" ["<<U<<","<<V<<"]";
Standard_Real V = _V;
@@ -569,13 +539,14 @@
//function : SetDomain
//purpose :
//=======================================================================
void IntAna_Curve::SetDomain(const Standard_Real DInf,
const Standard_Real DSup)
void IntAna_Curve::SetDomain(const Standard_Real theFirst,
const Standard_Real theLast)
{
if(DInf>=DSup) {
if (theLast <= theFirst)
{
throw Standard_DomainError("IntAna_Curve::Domain");
}
//
DomainInf=DInf;
DomainSup=DSup;
myFirstParameter = theFirst;
myLastParameter = theLast;
}

View File

@@ -21,16 +21,9 @@
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Standard_Real.hxx>
#include <Standard_Boolean.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <gp_Ax3.hxx>
class Standard_DomainError;
class gp_Cylinder;
class gp_Cone;
class gp_Pnt;
class gp_Vec;
#include <TColStd_ListOfReal.hxx>
//! Definition of a parametric Curve which is the result
//! of the intersection between two quadrics.
@@ -57,7 +50,7 @@ public:
Standard_EXPORT Standard_Boolean IsOpen() const;
//! Returns the paramatric domain of the curve.
Standard_EXPORT void Domain (Standard_Real& Theta1, Standard_Real& Theta2) const;
Standard_EXPORT void Domain(Standard_Real& theFirst, Standard_Real& theLast) const;
//! Returns TRUE if the function is constant.
Standard_EXPORT Standard_Boolean IsConstant() const;
@@ -77,11 +70,11 @@ public:
//! Tries to find the parameter of the point P on the curve.
//! If the method returns False, the "projection" is
//! impossible, and the value of Para is not significant.
//! If the method returns True, Para is the parameter of the
//! nearest intersection between the curve and the iso-theta
//! containing P.
Standard_EXPORT Standard_Boolean FindParameter (const gp_Pnt& P, Standard_Real& Para) const;
//! impossible.
//! If the method returns True at least one parameter has been found.
//! theParams is always sorted in ascending order.
Standard_EXPORT void FindParameter(const gp_Pnt& P,
TColStd_ListOfReal& theParams) const;
//! If flag is True, the Curve is not defined at the
//! first parameter of its domain.
@@ -91,10 +84,8 @@ public:
//! first parameter of its domain.
Standard_EXPORT void SetIsLastOpen (const Standard_Boolean Flag);
//! Protected function.
Standard_EXPORT void InternalUVValue (const Standard_Real Param, Standard_Real& U, Standard_Real& V, Standard_Real& A, Standard_Real& B, Standard_Real& C, Standard_Real& Co, Standard_Real& Si, Standard_Real& Di) const;
Standard_EXPORT void SetDomain (const Standard_Real Theta1, const Standard_Real Theta2);
//! Trims this curve
Standard_EXPORT void SetDomain(const Standard_Real theFirst, const Standard_Real theLast);
@@ -105,6 +96,8 @@ protected:
//! Protected function.
Standard_EXPORT gp_Pnt InternalValue (const Standard_Real Theta1, const Standard_Real Theta2) const;
//! Protected function.
Standard_EXPORT void InternalUVValue (const Standard_Real Param, Standard_Real& U, Standard_Real& V, Standard_Real& A, Standard_Real& B, Standard_Real& C, Standard_Real& Co, Standard_Real& Si, Standard_Real& Di) const;
@@ -133,8 +126,9 @@ private:
Standard_Boolean TwoCurves;
Standard_Boolean TakeZPositive;
Standard_Real Tolerance;
Standard_Real DomainInf;
Standard_Real DomainSup;
//! Internal fields defining the default domain
Standard_Real DomainInf, DomainSup;
Standard_Boolean RestrictedInf;
Standard_Boolean RestrictedSup;
Standard_Boolean firstbounded;
@@ -144,6 +138,9 @@ private:
Standard_Real Angle;
gp_Ax3 Ax3;
//! Trim boundaries
Standard_Real myFirstParameter, myLastParameter;
};

View File

@@ -28,6 +28,7 @@
//== C Y L I N D R E Q U A D R I Q U E
//======================================================================
#include <ElSLib.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Cone.hxx>
@@ -41,6 +42,75 @@
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//function : AddSpecialPoints
//purpose : Sometimes the boundaries theTheta1 and theTheta2 are
// computed with some inaccuracy. At that, some special points
// (cone apex or sphere pole(s)), which are true intersection
// points lie out of the domain [theTheta1, theTheta2] of the ALine.
// This function corrects these boundaries to make them be included
// in the domain of the ALine.
// Parameters Theta1 and Theta2 must be initialized
// before calling this function.
//=======================================================================
template <class gpSmth>
static void AddSpecialPoints(const IntAna_Quadric& theQuad,
const gpSmth& theGpObj,
Standard_Real& theTheta1,
Standard_Real& theTheta2)
{
const Standard_Real aPeriod = M_PI + M_PI;
const NCollection_List<gp_Pnt> &aLSP = theQuad.SpecialPoints();
if (aLSP.IsEmpty())
return;
Standard_Real aU = 0.0, aV = 0.0;
Standard_Real aMaxDelta = 0.0;
for (NCollection_List<gp_Pnt>::Iterator anItr(aLSP); anItr.More(); anItr.Next())
{
const gp_Pnt &aPt = anItr.Value();
ElSLib::Parameters(theGpObj, aPt, aU, aV);
const gp_Pnt aPProj(ElSLib::Value(aU, aV, theGpObj));
if (aPt.SquareDistance(aPProj) > Precision::SquareConfusion())
{
// aPt is not an intersection point
continue;
}
Standard_Real aDelta1 = Min(aU - theTheta1, 0.0),
aDelta2 = Max(aU - theTheta2, 0.0);
if (aDelta1 < -M_PI)
{
// Must be aDelta1 = Min(aU - theTheta1 + aPeriod, 0.0).
// But aU - theTheta1 + aPeriod >= 0 always.
aDelta1 = 0.0;
}
if (aDelta2 > M_PI)
{
// Must be aDelta2 = Max(aU - theTheta2 - aPeriod, 0.0).
// But aU - theTheta2 - aPeriod <= 0 always.
aDelta2 = 0.0;
}
const Standard_Real aDelta = Max(-aDelta1, aDelta2);
aMaxDelta = Max(aMaxDelta, aDelta);
}
if(aMaxDelta != 0.0)
{
theTheta1 -= aMaxDelta;
theTheta2 += aMaxDelta;
if ((theTheta2 - theTheta1) > aPeriod)
{
theTheta2 = theTheta1 + aPeriod;
}
}
}
//=======================================================================
//class : TrigonometricRoots
//purpose: Classe Interne (Donne des racines classees d un polynome trigo)
@@ -486,13 +556,15 @@ void IntAna_IntQuadQuad::Perform(const gp_Cylinder& Cyl,
//
qwet=MTF.Value(autrepar);
if(qwet>=0.) {
Standard_Real aParam = Theta1 + PIpPI;
AddSpecialPoints(Quad, Cyl, Theta1, aParam);
TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,Theta1,Theta1+PIpPI,
myEpsilon,Theta1,aParam,
UN_SEUL_Z_PAR_THETA,
Z_POSITIF);
NbCurves++;
TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,Theta1,Theta1+PIpPI,
myEpsilon,Theta1,aParam,
UN_SEUL_Z_PAR_THETA,
Z_NEGATIF);
NbCurves++;
@@ -534,6 +606,7 @@ void IntAna_IntQuadQuad::Perform(const gp_Cylinder& Cyl,
//ft
if((Theta3-Theta2)<5.e-8) {
//
AddSpecialPoints(Quad, Cyl, Theta1, Theta2);
TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,Theta1,Theta2,
UN_SEUL_Z_PAR_THETA,
@@ -546,6 +619,7 @@ void IntAna_IntQuadQuad::Perform(const gp_Cylinder& Cyl,
NbCurves++;
}
else {
AddSpecialPoints(Quad, Cyl, Theta1, Theta2);
TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,Theta1,Theta2,
DEUX_Z_PAR_THETA,

View File

@@ -28,6 +28,7 @@
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <IntAna_Quadric.hxx>
#include <ElSLib.hxx>
//----------------------------------------------------------------------
//--
@@ -85,22 +86,27 @@ IntAna_Quadric::IntAna_Quadric(const gp_Cylinder& Cyl) {
//----------------------------------------------------------------------
//-- Cone -----> Quadric
//----------------------------------------------------------------------
IntAna_Quadric::IntAna_Quadric(const gp_Cone& Cone) {
Cone.Coefficients(CXX,CYY,CZZ,CXY,CXZ,CYZ,CX,CY,CZ,CCte);
IntAna_Quadric::IntAna_Quadric(const gp_Cone& Cone)
{
SetQuadric(Cone);
}
void IntAna_Quadric::SetQuadric(const gp_Cone& Cone) {
Cone.Coefficients(CXX,CYY,CZZ,CXY,CXZ,CYZ,CX,CY,CZ,CCte);
const Standard_Real aVParam = -Cone.RefRadius() / Sin(Cone.SemiAngle());
mySpecialPoints.Append(ElSLib::Value(0.0, aVParam, Cone));
}
//----------------------------------------------------------------------
//-- Sphere -----> Quadric
//----------------------------------------------------------------------
void IntAna_Quadric::SetQuadric(const gp_Sphere& Sph) {
Sph.Coefficients(CXX,CYY,CZZ,CXY,CXZ,CYZ,CX,CY,CZ,CCte);
mySpecialPoints.Append(ElSLib::Value(0.0, -M_PI_2, Sph));
mySpecialPoints.Append(ElSLib::Value(0.0, M_PI_2, Sph));
}
IntAna_Quadric::IntAna_Quadric(const gp_Sphere& Sph) {
Sph.Coefficients(CXX,CYY,CZZ,CXY,CXZ,CYZ,CX,CY,CZ,CCte);
SetQuadric(Sph);
}
//----------------------------------------------------------------------
//-- Returns the Coefficients of the Quadric

View File

@@ -17,17 +17,8 @@
#ifndef _IntAna_Quadric_HeaderFile
#define _IntAna_Quadric_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Standard_Real.hxx>
class gp_Pln;
class gp_Sphere;
class gp_Cylinder;
class gp_Cone;
class gp_Ax3;
#include <NCollection_List.hxx>
//! This class provides a description of Quadrics by their
//! Coefficients in natural coordinate system.
@@ -78,7 +69,11 @@ public:
//! in the local coordinates system defined by Axis
Standard_EXPORT void NewCoefficients (Standard_Real& xCXX, Standard_Real& xCYY, Standard_Real& xCZZ, Standard_Real& xCXY, Standard_Real& xCXZ, Standard_Real& xCYZ, Standard_Real& xCX, Standard_Real& xCY, Standard_Real& xCZ, Standard_Real& xCCte, const gp_Ax3& Axis) const;
//! Returns the list of special points (with singularities)
const NCollection_List<gp_Pnt>& SpecialPoints() const
{
return mySpecialPoints;
}
protected:
@@ -101,7 +96,7 @@ private:
Standard_Real CY;
Standard_Real CZ;
Standard_Real CCte;
NCollection_List<gp_Pnt> mySpecialPoints;
};

View File

@@ -17,31 +17,21 @@
#ifndef _IntPatch_ALine_HeaderFile
#define _IntPatch_ALine_HeaderFile
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <Standard_Handle.hxx>
#include <IntAna_Curve.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
#include <IntPatch_SequenceOfPoint.hxx>
#include <IntPatch_Line.hxx>
#include <IntSurf_TypeTrans.hxx>
#include <IntSurf_Situation.hxx>
#include <Standard_Real.hxx>
#include <gp_Pnt.hxx>
class Standard_DomainError;
class Standard_OutOfRange;
#include <IntPatch_SequenceOfPoint.hxx>
#include <TColStd_ListOfReal.hxx>
class IntAna_Curve;
class IntPatch_Point;
class gp_Pnt;
class gp_Vec;
class IntPatch_ALine;
DEFINE_STANDARD_HANDLE(IntPatch_ALine, IntPatch_Line)
//! Implementation of an intersection line described by a
//! parametrised curve.
//! parametrized curve.
class IntPatch_ALine : public IntPatch_Line
{
@@ -97,13 +87,13 @@ public:
//! intersection.
Standard_Boolean D1 (const Standard_Real U, gp_Pnt& P, gp_Vec& Du);
//! Tries to find the parameter of the point P on the curve.
//! Tries to find the parameters of the point P on the curve.
//! If the method returns False, the "projection" is
//! impossible, and the value of Para is not significant.
//! If the method returns True, Para is the parameter of the
//! nearest intersection between the curve and the iso-theta
//! containing P.
Standard_Boolean FindParameter (const gp_Pnt& P, Standard_Real& Para) const;
//! impossible.
//! If the method returns True at least one parameter has been found.
//! theParams is always sorted in ascending order.
void FindParameter(const gp_Pnt& P,
TColStd_ListOfReal& theParams) const;
//! Returns True if the line has a known First point.
//! This point is given by the method FirstPoint().
@@ -126,6 +116,12 @@ public:
//! Returns the vertex of range Index on the line.
const IntPatch_Point& Vertex (const Standard_Integer Index) const;
//! Allows modifying the vertex with index theIndex on the line.
IntPatch_Point& ChangeVertex(const Standard_Integer theIndex)
{
return svtx.ChangeValue(theIndex);
}
//! Set the parameters of all the vertex on the line.
//! if a vertex is already in the line,
//! its parameter is modified

View File

@@ -62,9 +62,10 @@ inline Standard_Boolean IntPatch_ALine::D1(const Standard_Real U, gp_Pnt& P, gp_
return curv.D1u(U,P,Du); // D1u leve l exception DomainError
}
inline Standard_Boolean IntPatch_ALine::FindParameter(const gp_Pnt& P, Standard_Real& Para) const
inline void IntPatch_ALine::FindParameter(const gp_Pnt& theP,
TColStd_ListOfReal& theParams) const
{
return curv.FindParameter(P,Para);
curv.FindParameter(theP, theParams);
}
inline Standard_Boolean IntPatch_ALine::HasFirstPoint () const

View File

@@ -62,21 +62,20 @@ static void AddVertexPoint(Handle(IntSurf_LineOn2S)& theLine,
//function : IsPoleOrSeam
//purpose : Processes theVertex depending on its type
// (pole/apex/point on boundary etc.) and adds it in theLine.
// thePIsoRef is the reference point using in case when the
// value of correspond parameter cannot be precise.
// theSingularSurfaceID contains the ID of surface with
// special point (0 - none, 1 - theS1, 2 - theS2)
//=======================================================================
static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2,
const IntSurf_PntOn2S& thePIsoRef,
Handle(IntSurf_LineOn2S)& theLine,
IntPatch_Point &theVertex,
const Standard_Real* const theArrPeriods,
const Standard_Real theArrPeriods[4],
const Standard_Real theTol3d,
Standard_Integer& theSingularSurfaceID)
{
const Standard_Integer aNbPnts = theLine->NbPoints();
if(aNbPnts == 0)
return IntPatch_SPntNone;
theSingularSurfaceID = 0;
for(Standard_Integer i = 0; i < 2; i++)
@@ -94,8 +93,8 @@ static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1
{
if(IntPatch_SpecialPoints::
AddSingularPole((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
theLine->Value(aNbPnts), theTol3d, theVertex,
anApexPoint, isReversed, Standard_True))
thePIsoRef, theVertex, anApexPoint,
isReversed, Standard_True))
{
anAddedPType = IntPatch_SPntPole;
break;
@@ -107,8 +106,8 @@ static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1
{
if(IntPatch_SpecialPoints::
AddCrossUVIsoPoint((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
theLine->Value(aNbPnts), theTol3d,
anApexPoint, isReversed))
thePIsoRef, theTol3d,
anApexPoint, isReversed))
{
anAddedPType = IntPatch_SPntSeamUV;
break;
@@ -208,7 +207,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
//function : SetTol3D
//purpose :
//=======================================================================
void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
{
myTol3D = aTol;
}
@@ -216,7 +215,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
//function : Tol3D
//purpose :
//=======================================================================
Standard_Real IntPatch_ALineToWLine::Tol3D()const
Standard_Real IntPatch_ALineToWLine::Tol3D()const
{
return myTol3D;
}
@@ -224,7 +223,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
//function : SetTolTransition
//purpose :
//=======================================================================
void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
{
myTolTransition = aTol;
}
@@ -232,7 +231,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
//function : TolTransition
//purpose :
//=======================================================================
Standard_Real IntPatch_ALineToWLine::TolTransition()const
Standard_Real IntPatch_ALineToWLine::TolTransition()const
{
return myTolTransition;
}
@@ -240,7 +239,7 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
//function : SetTolOpenDomain
//purpose :
//=======================================================================
void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
{
myTolOpenDomain = aTol;
}
@@ -252,6 +251,48 @@ IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& t
{
return myTolOpenDomain;
}
//=======================================================================
//function : GetSectionRadius
//purpose :
//=======================================================================
Standard_Real IntPatch_ALineToWLine::GetSectionRadius(const gp_Pnt& thePnt3d) const
{
Standard_Real aRetVal = RealLast();
for (Standard_Integer i = 0; i < 2; i++)
{
const IntSurf_Quadric& aQuad = i ? myQuad2 : myQuad1;
if (aQuad.TypeQuadric() == GeomAbs_Cone)
{
const gp_Cone aCone = aQuad.Cone();
const gp_XYZ aRVec = thePnt3d.XYZ() - aCone.Apex().XYZ();
const gp_XYZ &aDir = aCone.Axis().Direction().XYZ();
aRetVal = Min(aRetVal, Abs(aRVec.Dot(aDir)*Tan(aCone.SemiAngle())));
}
else if (aQuad.TypeQuadric() == GeomAbs_Sphere)
{
const gp_Sphere aSphere = aQuad.Sphere();
const gp_XYZ aRVec = thePnt3d.XYZ() - aSphere.Location().XYZ();
const gp_XYZ &aDir = aSphere.Position().Direction().XYZ();
const Standard_Real aR = aSphere.Radius();
const Standard_Real aD = aRVec.Dot(aDir);
const Standard_Real aDelta = aR*aR - aD*aD;
if (aDelta <= 0.0)
{
aRetVal = 0.0;
break;
}
else
{
aRetVal = Min(aRetVal, Sqrt(aDelta));
}
}
}
return aRetVal;
}
//=======================================================================
//function : MakeWLine
//purpose :
@@ -282,10 +323,81 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
IntPatch_SequenceOfLine& theLines) const
{
const Standard_Integer aNbVert = theALine->NbVertex();
if (!aNbVert) {
if (aNbVert == 0)
{
return;
}
#if 0
//To draw ALine as a wire DRAW-object use the following code.
{
static int zzz = 0;
zzz++;
bool flShow = /*(zzz == 1)*/false;
if (flShow)
{
std::cout << " +++ DUMP ALine (begin) +++++" << std::endl;
Standard_Integer aI = 0;
const Standard_Real aStep = (theLPar - theFPar) / 9999.0;
for (Standard_Real aPrm = theFPar; aPrm < theLPar; aPrm += aStep)
{
const gp_Pnt aPP(theALine->Value(aPrm));
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
}
gp_Pnt aPP(theALine->Value(theLPar));
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
std::cout << " --- DUMP ALine (end) -----" << std::endl;
}
}
//Copy all output information and apply it as a TCL-code in DRAW.
//After that, use TCL-script below:
/* ********************************* Script (begin)
shape ww w
copy v1 vprev
for {set i 2} {$i <= 10000} {incr i} {
distmini dd vprev v$i;
if { [dval dd_val] > 1.0e-7} {
edge ee vprev v$i;
add ee ww;
copy v$i vprev;
}
}
********************************** Script (end) */
#endif
//The same points can be marked by different vertices.
//The code below unifies tolerances of all vertices
//marking the same points.
for (Standard_Integer i = 1; i < aNbVert; i++)
{
IntPatch_Point &aCurVert = theALine->ChangeVertex(i);
const IntSurf_PntOn2S &aCurrPt = aCurVert.PntOn2S();
const Standard_Real aCurToler = aCurVert.Tolerance();
for (Standard_Integer j = i + 1; j <= aNbVert; j++)
{
IntPatch_Point &aVert = theALine->ChangeVertex(j);
const IntSurf_PntOn2S &aNewPt = aVert.PntOn2S();
const Standard_Real aToler = aVert.Tolerance();
const Standard_Real aSumTol = aCurToler + aToler;
if (aCurrPt.IsSame(aNewPt, aSumTol))
{
aCurVert.SetTolerance(aSumTol);
aVert.SetTolerance(aSumTol);
}
}
}
const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion();
const Standard_Real aPrmTol = Max(1.0e-4*(theLPar - theFPar), Precision::PConfusion());
IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
NCollection_Array1<Standard_Real> aVertexParams(1, aNbVert);
@@ -299,7 +411,8 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
{
const Standard_Real aPar = theALine->Vertex(i).ParameterOnLine();
const IntPatch_Point& aVert = theALine->Vertex(i);
const Standard_Real aPar = aVert.ParameterOnLine();
aVertexParams(i) = aPar;
hasVertexBeenChecked(i) = Standard_False;
}
@@ -344,11 +457,24 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
}
}
Standard_Boolean isPointValid = Standard_False;
Standard_Real aTgMagn = 0.0;
{
gp_Pnt aPnt3d;
gp_Vec aTg;
theALine->D1(aParameter, aPnt3d, aTg);
if (GetSectionRadius(aPnt3d) < 5.0e-6)
{
// We cannot compute 2D-parameters of
// aPOn2S correctly.
isPointValid = Standard_False;
}
else
{
isPointValid = Standard_True;
}
aTgMagn = aTg.Magnitude();
Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
myQuad1.Parameters(aPnt3d, u1, v1);
@@ -372,13 +498,25 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
if (aPrePointExist == IntPatch_SPntPole)
{
Standard_Real aPrt = 0.5*(aPrevParam + theLPar);
for (Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
for (Standard_Integer i = aVertexParams.Lower();
i <= aVertexParams.Upper(); i++)
{
const Standard_Real aParam = aVertexParams(i);
if (aParam <= aPrevParam)
continue;
if ((aParam - aPrevParam) < aPrmTol)
{
const gp_Pnt aPnt3d(theALine->Value(aParam));
if (aPOn2S.Value().SquareDistance(aPnt3d) < Precision::SquareConfusion())
{
// i-th vertex is the same as a Pole/Apex.
// So, it should be ignored.
continue;
}
}
aPrt = 0.5*(aParam + aPrevParam);
break;
}
@@ -426,10 +564,17 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
if(hasVertexBeenChecked(i))
continue;
const IntPatch_Point &aVP = theALine->Vertex(i);
const Standard_Real aParam = aVertexParams(i);
if( ((aPrevParam < aParam) && (aParam <= aParameter)) ||
((aPrevParam == aParameter) && (aParam == aParameter)))
((aPrevParam == aParameter) && (aParam == aParameter))||
(aPOn2S.IsSame(aVP.PntOn2S(), aVP.Tolerance()) &&
(Abs(aVP.ParameterOnLine() - aParameter) < aPrmTol)))
{
//We have either jumped over the vertex or "fell" on the vertex.
//However, ALine can be self-interfered. Therefore, we need to check
//vertex parameter and 3D-distance together.
aVertexNumber = i;
break;
}
@@ -439,10 +584,14 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
if(aVertexNumber < 0)
{
StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn,
aStepMin, aStepMax, myTol3D, aStep);
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
aPrevLPoint = aPOn2S;
if (isPointValid)
{
StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn,
aStepMin, aStepMax, myTol3D, aStep);
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
aPrevLPoint = aPOn2S;
}
continue;
}
@@ -453,7 +602,33 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
// IsPoleOrSeam inserts new point in aLinOn2S if aVtx respects
//to some special point. Otherwise, aLinOn2S is not changed.
aPrePointExist = IsPoleOrSeam(myS1, myS2, aLinOn2S, aVtx,
// Find a point for reference parameter. It will be used
// if real parameter value cannot be precise (see comment to
// IsPoleOrSeam(...) function).
IntSurf_PntOn2S aPrefIso = aVtx.PntOn2S();
if (aLinOn2S->NbPoints() < 1)
{
for (Standard_Integer i = aVertexNumber + 1; i <= aVertexParams.Upper(); i++)
{
const Standard_Real aParam = aVertexParams(i);
if ((aParam - aVertexParams(aVertexNumber)) > Precision::PConfusion())
{
const Standard_Real aPrm = 0.5*(aParam + aVertexParams(aVertexNumber));
const gp_Pnt aPnt3d(theALine->Value(aPrm));
Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
myQuad1.Parameters(aPnt3d, u1, v1);
myQuad2.Parameters(aPnt3d, u2, v2);
aPrefIso.SetValue(aPnt3d, u1, v1, u2, v2);
break;
}
}
}
else
{
aPrefIso = aLinOn2S->Value(aLinOn2S->NbPoints());
}
aPrePointExist = IsPoleOrSeam(myS1, myS2, aPrefIso, aLinOn2S, aVtx,
anArrPeriods, aTol, aSingularSurfaceID);
const Standard_Real aCurVertParam = aVtx.ParameterOnLine();
@@ -463,6 +638,12 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
}
else
{
if (!isPointValid)
{
//Take a farther point of ALine (with greater parameter)
continue;
}
if(aVtx.Tolerance() > aTol)
{
aVtx.SetValue(aPOn2S);
@@ -507,7 +688,7 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
}
}
if(aPrePointExist != IntPatch_SPntNone)
if ((aPrePointExist != IntPatch_SPntNone) && (aLinOn2S->NbPoints() > 1))
break;
}//for(; !isLast; aParameter += aStep)
@@ -586,6 +767,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
if (aWLine->NbPnts() > 1)
{
aWLine->EnablePurging(Standard_False);
#ifdef INTPATCH_ALINETOWLINE_DEBUG
aWLine->Dump(0);
#endif
theLines.Append(aWLine);
}
}//while(aParameter < theLPar)
@@ -653,6 +837,19 @@ Standard_Boolean IntPatch_ALineToWLine::
const Standard_Real aR = IntPatch_PointLine::
CurvatureRadiusOfIntersLine(myS1, myS2, thePOn2S);
#if 0
{
static int zzz = 0;
zzz++;
std::cout << "*** R" << zzz << " (begin)" << std::endl;
Standard_Real aU1, aV1, aU2, aV2;
thePOn2S.Parameters(aU1, aV1, aU2, aV2);
std::cout << "Prms: " << aU1 << ", " << aV1 << ", " << aU2 << ", " << aV2 << std::endl;
std::cout << "Radius = " << aR << std::endl;
std::cout << "*** R" << zzz << " (end)" << std::endl;
}
#endif
if(aR < 0.0)
{
return Standard_False;

View File

@@ -80,11 +80,18 @@ protected:
const Standard_Real theMaxDeflection,
Standard_Real& theStep) const;
//! Compares distances from theMidPt to every quadrics with theMaxDeflection
//! (maximal distance of two ones is taken into account).
//! Returns the result of this comparison: -1 - small distance, +1 - big distance,
//! 0 - Dist == theMaxDeflection. Comparisons are done with internal tolerances.
Standard_EXPORT Standard_Integer CheckDeflection(const gp_XYZ& theMidPt,
const Standard_Real theMaxDeflection) const;
//! Returns radius of a circle obtained by intersection the quadric with a plane
//! goes through thePnt3d perpendicular to the quadric axis. This radius is computed
//! for both quadrics and minimal value is returned.
//! This check is made for cone and sphere only.
Standard_EXPORT Standard_Real GetSectionRadius(const gp_Pnt& thePnt3d) const;
private:

View File

@@ -42,24 +42,26 @@ static void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
const Standard_Boolean,
const Standard_Real);
static Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
const Handle(Adaptor3d_TopolTool)&,
const IntSurf_Quadric&,
const gp_Vec&,
const IntPatch_SequenceOfLine&,
TColStd_Array1OfInteger&,
TColStd_Array1OfInteger&,
const Standard_Integer,
const Standard_Boolean);
static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
const Handle(Adaptor3d_TopolTool)& Domain,
const IntSurf_Quadric& QuadSurf,
const gp_Vec& Normale,
const IntPatch_SequenceOfLine& slin,
TColStd_Array1OfInteger& Done,
TColStd_Array1OfInteger& UsedLine,
const Standard_Integer Index,
const Standard_Boolean OnFirst,
const Standard_Real theToler);
static Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
const Handle(Adaptor3d_TopolTool)&,
const IntSurf_Quadric&,
const gp_Vec&,
const gp_Vec&,
const Handle(IntPatch_Line)&,
TColStd_Array1OfInteger&,
const Standard_Integer);
static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
const Handle(Adaptor3d_TopolTool)& Domain,
const IntSurf_Quadric& QuadSurf,
const gp_Vec& Normale,
const gp_Vec& Vtgint,
const Handle(IntPatch_Line)& lin,
TColStd_Array1OfInteger& Done,
const Standard_Integer Index,
const Standard_Real theToler);
static Standard_Boolean SingleLine (const gp_Pnt&,
const Handle(IntPatch_Line)&,
@@ -68,17 +70,19 @@ static Standard_Boolean SingleLine (const gp_Pnt&,
gp_Vec&);
static Standard_Boolean FindLine (gp_Pnt&,
const IntPatch_SequenceOfLine&,
const Standard_Real,
Standard_Real&,
gp_Vec&,
Standard_Integer&,
Standard_Integer,
const Handle(Adaptor2d_HCurve2d)&,
Standard_Real&,
gp_Pnt& pointonarc,
const IntSurf_Quadric&);
static Standard_Boolean FindLine(gp_Pnt& Psurf,
const IntPatch_SequenceOfLine& slin,
const Standard_Real Tol,
TColStd_ListOfReal& theLParams,
gp_Vec& Vtgtint,
Standard_Integer& theLineIdx,
Standard_Integer OnlyThisLine,
const Handle(Adaptor2d_HCurve2d)& thearc,
Standard_Real& theparameteronarc,
gp_Pnt& thepointonarc,
const IntSurf_Quadric& QuadSurf1,
const IntSurf_Quadric& QuadSurf2,
Standard_Real& theOutputToler);
static void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
IntPatch_SequenceOfLine&,
@@ -102,8 +106,7 @@ Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
gp_Pnt& thepointonarc,
const IntSurf_Quadric& QuadSurf,
const Standard_Real u0alin,
const Standard_Real u1alin,
Standard_Real& actualdist) {
const Standard_Real u1alin) {
Standard_Real dtheta,theta;
#ifdef OCCT_DEBUG
//Standard_Real u,v,A,B,C,cost,sint,sign;
@@ -221,7 +224,6 @@ Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
thepointonarc = alin->Value(para);
cpasok=Standard_False;
//-- printf("\nt:%d",nbiter);
actualdist = bestdist;
return(Standard_True);
}
else {
@@ -249,7 +251,6 @@ Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
_theparameteronarc=bestpara;
thepointonarc = alin->Value(para);
//-- printf("\nT:%d",nbiter);
actualdist=bestdist;
return(Standard_True);
}
//-- printf("\nF:%d",nbiter);
@@ -383,7 +384,7 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
//
Standard_Integer i,k;
Standard_Integer linenumber;
Standard_Real paraint = 0.,currentparameter,tolerance;
Standard_Real currentparameter,tolerance;
Standard_Real U1,V1,U2,V2;
Standard_Boolean goon;
@@ -429,10 +430,10 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
#endif
goon = MultiplePoint(listpnt,Domain,QuadSurf,Normale,slin,Done, UsedLine,
i,OnFirst);
i, OnFirst, Tolarc);
}
if (goon) {
Standard_Boolean linefound;
Standard_Boolean linefound = Standard_False;
for(Standard_Integer indiceline = 1; indiceline <=slin.Length(); indiceline++) {
if( UsedLine(indiceline) != 0 )
@@ -470,8 +471,11 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
// Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
gp_Pnt pointonarc;
Vtgint.SetCoord(0,0,0);
linefound = FindLine(Psurf,slin,tolerance,paraint,Vtgint,linenumber,indiceline,
currentarc,currentparameter,pointonarc,QuadSurf);
Standard_Real aVertTol = Tolarc;
TColStd_ListOfReal aLParams;
linefound = FindLine(Psurf, slin, tolerance, aLParams, Vtgint, linenumber,
indiceline, currentarc, currentparameter,
pointonarc, QuadSurf, OtherQuad, aVertTol);
if (linefound) {
#if 1
@@ -493,14 +497,14 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
// deuxieme surface
goon = PointOnSecondDom (listpnt, Domain, QuadSurf, Normale,
Vtgint, lin, Done, i);
Vtgint, lin, Done, i, aVertTol);
}
if (goon) {
//-- Modification du 4 avril 97 tolerance->Tolarc
//-- on replace sur le vertex la tolerance d entree et
//-- non la tolerance qui a servi au FindLine
solpnt.SetValue(Psurf,Tolarc,Standard_False);
solpnt.SetValue(Psurf, aVertTol, Standard_False);
U1 = p2d.X(); V1 = p2d.Y();
OtherQuad.Parameters(Psurf,U2,V2);
@@ -513,7 +517,6 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
Recadre(S1,S2,U2,V2,U1,V1);
solpnt.SetParameters(U2,V2,U1,V1);
}
solpnt.SetParameter(paraint);
if (! currentpointonrst.IsNew()) {
vtx = currentpointonrst.Vertex();
@@ -532,12 +535,21 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
}
solpnt.SetArc(OnFirst,currentarc, currentparameter,
Transline,Transarc);
if (TheType == IntPatch_Analytic) {
Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(solpnt);
}
else {
Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(solpnt);
}
for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
anItr.More(); anItr.Next())
{
solpnt.SetParameter(anItr.Value());
if (TheType == IntPatch_Analytic)
{
Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
}
else
{
Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
}
}
Done(i) = 1;
if (goon) {
@@ -550,6 +562,7 @@ void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
}
else if (Domain->Identical(vtx, vtxbis)) {
solpnt.SetVertex(OnFirst,vtxbis);
solpnt.SetTolerance(Tolarc);
currentarc = currentpointonrst.Arc();
currentparameter = currentpointonrst.Parameter();
@@ -599,7 +612,8 @@ Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBound
TColStd_Array1OfInteger& Done,
TColStd_Array1OfInteger& UsedLine,
const Standard_Integer Index,
const Standard_Boolean OnFirst) {
const Standard_Boolean OnFirst,
const Standard_Real theToler) {
// Traitement des points "multiples".
@@ -696,7 +710,7 @@ Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBound
intpt.SetArc(OnFirst,currentarc,currentparameter,
Transline,Transarc);
intpt.SetTolerance(theToler);
if (TheType == IntPatch_Analytic) {
Handle(IntPatch_ALine)::DownCast (slinValueii)->Replace(jj,intpt);
@@ -728,6 +742,7 @@ Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBound
}
intpt.SetArc(OnFirst,currentarc,currentparameter,
Transline,Transarc);
intpt.SetTolerance(theToler);
if (TheType == IntPatch_Analytic) {
Handle(IntPatch_ALine)::DownCast (slinValueii)->AddVertex(intpt);
}
@@ -770,7 +785,8 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
const gp_Vec& Vtgint,
const Handle(IntPatch_Line)& lin,
TColStd_Array1OfInteger& Done,
const Standard_Integer Index)
const Standard_Integer Index,
const Standard_Real theToler)
// Duplication des points sur domaine de l autre surface.
@@ -841,6 +857,8 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
}
intpt.SetArc(Standard_False,currentarc,currentparameter,
Transline,Transarc);
intpt.SetTolerance(theToler);
if (TheType == IntPatch_Analytic) {
Handle(IntPatch_ALine)::DownCast (lin)->Replace(jj,intpt);
}
@@ -871,6 +889,7 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
}
intpt.SetArc(Standard_False,currentarc,currentparameter,
Transline,Transarc);
intpt.SetTolerance(theToler);
if (TheType == IntPatch_Analytic) {
Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(intpt);
}
@@ -905,31 +924,36 @@ Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBou
Standard_Boolean FindLine (gp_Pnt& Psurf,
const IntPatch_SequenceOfLine& slin,
const Standard_Real Tol,
Standard_Real& Paraint,
gp_Vec& Vtgtint,
Standard_Integer& Range,
Standard_Integer OnlyThisLine,
const Handle(Adaptor2d_HCurve2d)& thearc,
Standard_Real& theparameteronarc,
gp_Pnt& thepointonarc,
const IntSurf_Quadric& QuadSurf)
{
Standard_Boolean FindLine(gp_Pnt& Psurf,
const IntPatch_SequenceOfLine& slin,
const Standard_Real Tol,
TColStd_ListOfReal& theLParams,
gp_Vec& Vtgtint,
Standard_Integer& theLineIdx,
Standard_Integer OnlyThisLine,
const Handle(Adaptor2d_HCurve2d)& thearc,
Standard_Real& theparameteronarc,
gp_Pnt& thepointonarc,
const IntSurf_Quadric& QuadSurf1,
const IntSurf_Quadric& QuadSurf2,
Standard_Real& theOutputToler)
{
if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
return Standard_False;
// Traitement du point de depart ayant pour representation Psurf
// dans l espace. On recherche la ligne d intersection contenant ce point.
// On a en sortie la ligne, et le parametre et sa tangente du point sur
// la ligne d intersection.
Standard_Real distmin = RealLast();
Standard_Real dist,para;
const Standard_Real aSqTol = Tol*Tol;
Standard_Real aSqDistMin = RealLast();
Standard_Real aSqDist, para;
Standard_Real lower,upper;
gp_Pnt pt;
Standard_Integer i;
IntPatch_IType typarc;
Standard_Real aParaInt = RealLast();
Standard_Integer nblin = slin.Length();
for (i=1; i<=nblin; i++) {
if(OnlyThisLine) { i=OnlyThisLine; nblin=0; }
@@ -961,11 +985,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
if (para <= upper && para >= lower) {
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Line());
dist = Psurf.Distance(pt);
if (dist< distmin) {
distmin = dist;
Paraint = para;
Range = i;
aSqDist = Psurf.SquareDistance(pt);
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
{
aSqDistMin = aSqDist;
aParaInt = para;
theLineIdx = i;
}
}
}
@@ -977,11 +1002,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
(para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
(para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Circle());
dist = Psurf.Distance(pt);
if (dist< distmin) {
distmin = dist;
Paraint = para;
Range = i;
aSqDist = Psurf.SquareDistance(pt);
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
{
aSqDistMin = aSqDist;
aParaInt = para;
theLineIdx = i;
}
}
}
@@ -993,11 +1019,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
(para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
(para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse());
dist = Psurf.Distance(pt);
if (dist< distmin) {
distmin = dist;
Paraint = para;
Range = i;
aSqDist = Psurf.SquareDistance(pt);
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
{
aSqDistMin = aSqDist;
aParaInt = para;
theLineIdx = i;
}
}
}
@@ -1030,24 +1057,28 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
Standard_Real parabis = para+0.0000001;
pt = ElCLib::Value(para,Parab);
dist = Psurf.Distance(pt);
aSqDist = Psurf.SquareDistance(pt);
gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
Standard_Real distbis = Psurf.Distance(ptbis);
Standard_Real ddist = distbis-dist;
const gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
const Standard_Real distbis = Psurf.Distance(ptbis);
const Standard_Real aDist = Sqrt(aSqDist);
const Standard_Real ddist = distbis - aDist;
//--cout<<" para: "<<para<<" dist:"<<dist<<" ddist:"<<ddist<<endl;
if (dist< distmin) {
distmin = dist;
Paraint = para;
Range = i;
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
{
aSqDistMin = aSqDist;
aParaInt = para;
theLineIdx = i;
}
if(dist<1.0e-9 && dist>-1.0e-9) { amelioration=100; }
if (aSqDist < Precision::SquarePConfusion())
{
amelioration = 100;
}
if(ddist>1.0e-9 || ddist<-1.0e-9 ) {
para=para-dist*(parabis-para)/ddist;
para = para - aDist*(parabis - para) / ddist;
}
else {
amelioration=100;
@@ -1065,11 +1096,12 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
if (para <= upper && para >= lower) {
pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola());
dist = Psurf.Distance(pt);
if (dist< distmin) {
distmin = dist;
Paraint = para;
Range = i;
aSqDist = Psurf.SquareDistance(pt);
if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
{
aSqDistMin = aSqDist;
aParaInt = para;
theLineIdx = i;
}
}
}
@@ -1077,17 +1109,33 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
case IntPatch_Analytic :
{
Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (lin));
Standard_Boolean FindIsOk = alin->FindParameter(Psurf,para);
if (FindIsOk) {
pt = alin->Value(para);
dist = Psurf.Distance(pt);
if (dist< distmin) {
distmin = dist;
Paraint = para;
Range = i;
}
}
Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
TColStd_ListOfReal aLParams;
alin->FindParameter(Psurf, aLParams);
if (!aLParams.IsEmpty())
{
// All found distances are already in some internal tolerance
// set in alin->FindParameter(...) method.
aSqDist = RealLast();
for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
anItr.More(); anItr.Next())
{
pt = alin->Value(anItr.Value());
const Standard_Real aSqD = Psurf.SquareDistance(pt);
if (aSqD < aSqDist)
{
aSqDist = aSqD;
}
}
if (aSqDist < aSqDistMin)
{
aSqDistMin = aSqDist;
theLParams = aLParams;
theLineIdx = i;
}
}
else {
//-- le point n a pas ete trouve par bete projection.
//-- on essaie l intersection avec la restriction en 2d
@@ -1096,19 +1144,20 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
// Standard_Real anpara=para;
//#endif
gp_Pnt CopiePsurf=Psurf;
Standard_Boolean IntersectIsOk=IntersectionWithAnArc(CopiePsurf,alin,para,thearc,theparamonarc,thepointonarc,QuadSurf,lower,upper,dist);
//--printf("\nIntersectionWithAnArc %d \n Psurf(%g,%g,%g)->(%g,%g,%g) dist=%g\n para(%g)->(%g)\n paraonarc(%g)->(%g)",
//-- ok,Psurf.X(),Psurf.Y(),Psurf.Z(),thepointonarc.X(),thepointonarc.Y(),thepointonarc.Z(),dist,
//-- anpara,para,theparameteronarc,theparamonarc);
dist = CopiePsurf.Distance(Psurf);
Standard_Boolean IntersectIsOk = IntersectionWithAnArc(CopiePsurf, alin, para,
thearc, theparamonarc,
thepointonarc,
QuadSurf1,
lower, upper);
aSqDist = CopiePsurf.SquareDistance(Psurf);
if(IntersectIsOk) {
if(dist<Tol) {
if (aSqDist < aSqTol)
{
theparameteronarc = theparamonarc;
Psurf = thepointonarc;
distmin = dist;
Paraint = para;
Range = i;
aSqDistMin = aSqDist;
theLParams.Append(para);
theLineIdx = i;
}
}
}
@@ -1124,86 +1173,47 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
}
}
if (distmin > Tol) {
if (aSqDistMin == RealLast())
return Standard_False;
}
typarc = slin.Value(Range)->ArcType();
theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
// Calcul de la tangente.
typarc = slin.Value(theLineIdx)->ArcType();
// Computation of tangent vector
switch (typarc) {
case IntPatch_Lin :
Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(Range)))->Line().Direction();
theLParams.Append(aParaInt);
Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
break;
case IntPatch_Circle :
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Circle(),1);
theLParams.Append(aParaInt);
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
break;
case IntPatch_Ellipse :
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Ellipse(),1);
theLParams.Append(aParaInt);
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
break;
case IntPatch_Parabola :
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Parabola(),1);
theLParams.Append(aParaInt);
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
break;
case IntPatch_Hyperbola :
Vtgtint = ElCLib::DN(Paraint,(*((Handle(IntPatch_GLine)*)&slin(Range)))->Hyperbola(),1);
theLParams.Append(aParaInt);
Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
break;
case IntPatch_Analytic:
{
const Handle(IntPatch_ALine)& alin = (*((Handle(IntPatch_ALine)*)&slin(Range)));
Standard_Boolean abid = alin->D1(Paraint,pt,Vtgtint);
if (!abid) {
Standard_Real domaininf,domainsup,paramproche;
Standard_Boolean boolbid;
domaininf = alin->FirstParameter(boolbid);
domainsup = alin->LastParameter(boolbid);
if(Paraint>=domaininf && Paraint<=domainsup) {
Standard_Real DeltaParam = 0.001 * (domainsup-domaininf);
if(Paraint-domaininf >= domainsup-Paraint) {
//-- On decale le point vers le parametre le plus eloigne.
DeltaParam = -DeltaParam;
}
Standard_Integer kountbid = 0;
Standard_Boolean bornok = Standard_True;
paramproche = Paraint;
do {
paramproche+=DeltaParam;
kountbid++;
gp_Pnt ptbid;
if(paramproche>=domaininf && paramproche<=domainsup) {
abid = alin->D1(paramproche,ptbid,Vtgtint);
}
else {
bornok = Standard_False;
}
}
while(abid==Standard_False && kountbid<5 && bornok);
//-- Attention aux points de tangence (croisement de 4 lignes )
bornok = Standard_True;
kountbid = 0;
gp_Vec OVtgtint(0.0,0.0,0.0);
paramproche = Paraint;
do {
paramproche-=DeltaParam;
kountbid++;
gp_Pnt ptbid;
if(paramproche>=domaininf && paramproche<=domainsup) {
abid = alin->D1(paramproche,ptbid,OVtgtint);
}
else {
bornok = Standard_False;
}
}
while(abid==Standard_False && kountbid<5 && bornok);
if(bornok) {
paramproche = Vtgtint.Dot(OVtgtint);
if(paramproche<=0.0) abid = Standard_False;
}
}
if(!abid) {
//-- cout << "Pb sur Calcul de derivee 111 " << endl;
Vtgtint.SetCoord(0.,0.,0.);
}
if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
{
//Previously (before the fix #29807) this code tried to process case
//when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
//computed Vtgtint input argument value. Currently, any singularities
//must be processed by high-level algorithms (IntPatch_SpecialPoints class).
//Therefore this code has been deleted as deprecated.
Vtgtint.SetCoord(0.0, 0.0, 0.0);
}
}
break;
@@ -1218,19 +1228,20 @@ Standard_Boolean FindLine (gp_Pnt& Psurf,
return Standard_True;
}
Standard_Boolean SingleLine (const gp_Pnt& Psurf,
const Handle(IntPatch_Line)& lin,
const Standard_Real Tol,
Standard_Real& Paraint,
gp_Vec& Vtgtint) {
// Traitement du point de depart ayant pour representation Psurf
// dans l espace. On le replace sur la ligne d intersection; On a en sortie
// son parametre et sa tangente sur la ligne d intersection.
// La fonction renvoie False si le point projete est a une distance
// superieure a Tol du point a projeter.
//=======================================================================
//function : SingleLine
//purpose : Traitement du point de depart ayant pour representation Psurf
// dans l espace. On le replace sur la ligne d intersection; On a en sortie
// son parametre et sa tangente sur la ligne d intersection.
// La fonction renvoie False si le point projete est a une distance
// superieure a Tol du point a projeter.
//=======================================================================
Standard_Boolean SingleLine(const gp_Pnt& Psurf,
const Handle(IntPatch_Line)& lin,
const Standard_Real Tol,
Standard_Real& Paraint,
gp_Vec& Vtgtint)
{
IntPatch_IType typarc = lin->ArcType();
Standard_Real parproj = 0.;
@@ -1238,7 +1249,6 @@ Standard_Boolean SingleLine (const gp_Pnt& Psurf,
gp_Pnt ptproj;
Standard_Boolean retvalue;
switch (typarc) {
case IntPatch_Lin :
parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
@@ -1262,46 +1272,30 @@ Standard_Boolean SingleLine (const gp_Pnt& Psurf,
break;
case IntPatch_Analytic :
{
Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (lin));
Standard_Boolean ok = alin->FindParameter(Psurf,parproj);
if (ok) {
gp_Pnt ptbid;
Standard_Boolean bid = alin->D1(parproj,ptbid,tgint);
if (!bid) {
Standard_Real domaininf,domainsup,paramproche;
Standard_Boolean boolbid;
domaininf = alin->FirstParameter(boolbid);
domainsup = alin->LastParameter(boolbid);
if(parproj>=domaininf && parproj<=domainsup) {
Standard_Real DeltaParam = 0.001 * (domainsup-domaininf);
if(parproj-domaininf >= domainsup-parproj) {
//-- On decale le point vers le parametre le plus eloigne.
DeltaParam = -DeltaParam;
}
Standard_Integer kountbid = 0;
paramproche = parproj;
do {
paramproche+=DeltaParam;
kountbid++;
bid = alin->D1(paramproche,ptbid,tgint);
}
while(bid==Standard_False && kountbid<5);
ptproj = Psurf;
}
if(!bid) {
//-- cout << "Pb sur Calcul de derivee ALine " << endl;
tgint.SetCoord(0.,0.,0.);
return(Standard_False);
}
}
else {
ptproj = Psurf;
}
Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
TColStd_ListOfReal aLParams;
alin->FindParameter(Psurf, aLParams);
if (!aLParams.IsEmpty())
{
ptproj = Psurf;
parproj = aLParams.Last();
gp_Pnt aPtemp;
if (!alin->D1(parproj, aPtemp, tgint))
{
//Previously (before the fix #29807) this code tried to process case
//when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
//computed Vtgtint input argument value. Currently, any singularities
//must be processed by high-level algorithms (IntPatch_SpecialPoints class).
//Therefore this code has been deleted as deprecated.
tgint.SetCoord(0.0, 0.0, 0.0);
}
}
else {
//-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
//-- cout << " Find Parameter"<<endl;
return Standard_False;
else
{
//-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
//-- cout << " Find Parameter"<<endl;
return Standard_False;
}
}
break;
@@ -1485,6 +1479,7 @@ void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
if (EdgeDegenere==Standard_False && dofirst) {
if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
ptvtx.SetMultiple(Standard_True);
ptvtx.SetTolerance(TolArc);
if (typ == IntPatch_Analytic) {
Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
}
@@ -1549,6 +1544,7 @@ void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
if (EdgeDegenere==Standard_False && dolast) {
if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
ptvtx.SetMultiple(Standard_True);
ptvtx.SetTolerance(TolArc);
if (typ == IntPatch_Analytic) {
Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
}
@@ -1988,6 +1984,7 @@ void ProcessRLine (IntPatch_SequenceOfLine& slin,
}
if (keeppoint) {
Ptvtx.SetMultiple(Standard_True);
Ptvtx.SetTolerance(_TolArc);
newptvtx.SetMultiple(Standard_True);
if (typ2 == IntPatch_Analytic) {

View File

@@ -307,11 +307,15 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
}
nbpt = solrst.NbPoints();
nbseg= solrst.NbSegments();
for (i=1; i<= nbpt; i++) {
pnt1.Append(solrst.Point(i));
for (i = 1; i <= nbpt; i++)
{
const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
pnt1.Append(aPt);
}
for (i=1; i<= nbseg; i++) {
edg1.Append(solrst.Segment(i));
for (i = 1; i <= nbseg; i++)
{
const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
edg1.Append(aSegm);
}
nosolonS1 = (nbpt == 0) && (nbseg == 0);
@@ -335,15 +339,19 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
if (solrst.AllArcSolution() && typs1 == typs2) {
all2 = Standard_True;
}
nbpt = solrst.NbPoints();
nbseg= solrst.NbSegments();
for (i=1; i<= nbpt; i++) {
pnt2.Append(solrst.Point(i));
const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
pnt2.Append(aPt);
}
for (i=1; i<= nbseg; i++) {
edg2.Append(solrst.Segment(i));
const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
edg2.Append(aSegm);
}
nosolonS2 = (nbpt == 0) && (nbseg == 0);
if (nosolonS2 && all2) { // cas de face sans restrictions

View File

@@ -29,12 +29,10 @@ static void ShortCosForm( const Standard_Real theCosFactor,
Standard_Real& theCoeff,
Standard_Real& theAngle);
//
static
Standard_Boolean ExploreCurve(const gp_Cylinder& aCy,
const gp_Cone& aCo,
IntAna_Curve& aC,
const Standard_Real aTol,
IntAna_ListOfCurve& aLC);
static Standard_Boolean ExploreCurve(const gp_Cone& theCo,
IntAna_Curve& aC,
const Standard_Real aTol,
IntAna_ListOfCurve& aLC);
static Standard_Boolean InscribePoint(const Standard_Real theUfTarget,
const Standard_Real theUlTarget,
@@ -511,13 +509,6 @@ private:
const Standard_Boolean myIsReverse;
};
static
Standard_Boolean ExploreCurve(const gp_Cylinder& aCy,
const gp_Cone& aCo,
IntAna_Curve& aC,
const Standard_Real aTol,
IntAna_ListOfCurve& aLC);
static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1,
const IntSurf_Quadric& theQuad2,
const Handle(IntSurf_LineOn2S)& theLine,
@@ -840,6 +831,7 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura
if (!procf) {
d=ptf.Distance(ptsol.Value());
if (d <= Tol) {
ptsol.SetTolerance(Tol);
if (!ptsol.IsMultiple()) {
//-- le point ptsol (de aligold) est declare multiple sur aligold
Multpoint = Standard_True;
@@ -858,6 +850,7 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura
}
if (!procl) {
if (ptl.Distance(ptsol.Value()) <= Tol) {
ptsol.SetTolerance(Tol);
if (!ptsol.IsMultiple()) {
Multpoint = Standard_True;
ptsol.SetMultiple(Standard_True);
@@ -888,6 +881,8 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura
}
}
}
ptsol.SetTolerance(Tol);
if (!procf && !procl) {
Quad1.Parameters(ptf,U1,V1);
Quad2.Parameters(ptf,U2,V2);
@@ -4136,7 +4131,7 @@ Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
//curvsol = anaint.Curve(i);
aC=anaint.Curve(i);
aLC.Clear();
ExploreCurve(Cy, Co, aC, 10.*Tol, aLC);
ExploreCurve(Co, aC, 10.*Tol, aLC);
//
aIt.Initialize(aLC);
for (; aIt.More(); aIt.Next()) {
@@ -4209,61 +4204,69 @@ Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
}
//=======================================================================
//function : ExploreCurve
//purpose :
//purpose : Splits aC on several curves in the cone apex points.
//=======================================================================
Standard_Boolean ExploreCurve(const gp_Cylinder& ,//aCy,
const gp_Cone& aCo,
IntAna_Curve& aC,
const Standard_Real aTol,
IntAna_ListOfCurve& aLC)
Standard_Boolean ExploreCurve(const gp_Cone& theCo,
IntAna_Curve& theCrv,
const Standard_Real theTol,
IntAna_ListOfCurve& theLC)
{
Standard_Boolean bFind=Standard_False;
Standard_Real aTheta, aT1, aT2, aDst;
gp_Pnt aPapx, aPx;
const Standard_Real aSqTol = theTol*theTol;
const gp_Pnt aPapx(theCo.Apex());
Standard_Real aT1, aT2;
theCrv.Domain(aT1, aT2);
theLC.Clear();
//
//aC.Dump();
//
aLC.Clear();
aLC.Append(aC);
//
aPapx=aCo.Apex();
//
aC.Domain(aT1, aT2);
//
aPx=aC.Value(aT1);
aDst=aPx.Distance(aPapx);
if (aDst<aTol) {
return bFind;
TColStd_ListOfReal aLParams;
theCrv.FindParameter(aPapx, aLParams);
if (aLParams.IsEmpty())
{
theLC.Append(theCrv);
return Standard_False;
}
aPx=aC.Value(aT2);
aDst=aPx.Distance(aPapx);
if (aDst<aTol) {
return bFind;
for (TColStd_ListIteratorOfListOfReal anItr(aLParams); anItr.More(); anItr.Next())
{
Standard_Real aPrm = anItr.Value();
if ((aPrm - aT1) < Precision::PConfusion())
continue;
Standard_Boolean isLast = Standard_False;
if ((aT2 - aPrm) < Precision::PConfusion())
{
aPrm = aT2;
isLast = Standard_True;
}
const gp_Pnt aP = theCrv.Value(aPrm);
const Standard_Real aSqD = aP.SquareDistance(aPapx);
if (aSqD < aSqTol)
{
IntAna_Curve aC1 = theCrv;
aC1.SetDomain(aT1, aPrm);
aT1 = aPrm;
theLC.Append(aC1);
}
if (isLast)
break;
}
//
bFind=aC.FindParameter(aPapx, aTheta);
if (!bFind){
return bFind;
if (theLC.IsEmpty())
{
theLC.Append(theCrv);
return Standard_False;
}
//
aPx=aC.Value(aTheta);
aDst=aPx.Distance(aPapx);
if (aDst>aTol) {
return !bFind;
if ((aT2 - aT1) > Precision::PConfusion())
{
IntAna_Curve aC1 = theCrv;
aC1.SetDomain(aT1, aT2);
theLC.Append(aC1);
}
//
// need to be splitted at aTheta
IntAna_Curve aC1, aC2;
//
aC1=aC;
aC1.SetDomain(aT1, aTheta);
aC2=aC;
aC2.SetDomain(aTheta, aT2);
//
aLC.Clear();
aLC.Append(aC1);
aLC.Append(aC2);
//
return bFind;
return Standard_True;
}

View File

@@ -19,6 +19,7 @@
#include <Adaptor3d_HSurface.hxx>
#include <Adaptor3d_TopolTool.hxx>
#include <ElCLib.hxx>
#include <ElSLib.hxx>
#include <IntPatch_ArcFunction.hxx>
#include <IntPatch_PointLine.hxx>
#include <IntPatch_RLine.hxx>
@@ -87,6 +88,7 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
const Handle(IntSurf_LineOn2S)& theLine,
const Standard_Boolean IsReversed,
const Standard_Integer theRefIndex,
const Standard_Real theTol3D,
const Standard_Real theDeltaMax)
{
if((theRefIndex < 1) || (theRefIndex >= theLine->NbPoints()))
@@ -96,6 +98,8 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
Standard_Real aUQRef, aVQRef, aUPRef, aVPRef;
Standard_Real aUQNext, aVQNext, aUPNext, aVPNext;
const gp_Pnt &aP3d = theLine->Value(theRefIndex + 1).Value();
if(IsReversed)
{
theLine->Value(theRefIndex).Parameters (aUPRef, aVPRef, aUQRef, aVQRef);
@@ -109,6 +113,28 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
const GeomAbs_SurfaceType aType = theQSurf->GetType();
if ((aType == GeomAbs_Cone) &&
(theQSurf->Cone().Apex().SquareDistance(aP3d) < theTol3D*theTol3D))
{
return IntPatch_SPntPoleSeamU;
}
else if (aType == GeomAbs_Sphere)
{
const Standard_Real aSqTol = theTol3D*theTol3D;
gp_Pnt aP(ElSLib::Value(0.0, M_PI_2, theQSurf->Sphere()));
if (aP.SquareDistance(aP3d) < aSqTol)
{
return IntPatch_SPntPoleSeamU;
}
aP = ElSLib::Value(0.0, -M_PI_2, theQSurf->Sphere());
if (aP.SquareDistance(aP3d) < aSqTol)
{
return IntPatch_SPntPoleSeamU;
}
}
const Standard_Real aDeltaU = Abs(aUQRef - aUQNext);
if((aType != GeomAbs_Torus) && (aDeltaU < theDeltaMax))
@@ -2628,6 +2654,15 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
PrePoint, IsReversed))
{
sline->Add(PrePoint);
//Avoid adding duplicate points.
for (;aFindex <= aLindex; aFindex++)
{
if (!PrePoint.IsSame(aSSLine->Value(aFindex), theTolTang))
{
break;
}
}
}
else
{
@@ -2658,7 +2693,8 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
DetectOfBoundaryAchievement(theQSurf, IsReversed, aSSLine,
k, aTOL2D, sline, isOnBoundary);
aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed, k - 1, aDeltaUmax);
aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed,
k - 1, theTolTang, aDeltaUmax);
if (isOnBoundary && (aPrePointExist != IntPatch_SPntPoleSeamU))
{
@@ -2742,7 +2778,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
aSupBound(3) = theQSurf->LastUParameter();
IntPatch_SpecialPoints::
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False,
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False, 0.0,
aTol, aStartPoint, anInfBound, aSupBound,
aNewPoint, IsReversed);
}
@@ -2752,9 +2788,10 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
IntPatch_Point aVert;
aVert.SetValue(aRefPt);
aVert.SetTolerance(theTolTang);
if(IntPatch_SpecialPoints::
AddSingularPole(theQSurf, thePSurf, aRefPt, theTolTang,
AddSingularPole(theQSurf, thePSurf, aRefPt,
aVert, aNewPoint, IsReversed))
{
aPrePointExist = IntPatch_SPntPole;
@@ -2823,7 +2860,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
aSupBound(3) = theQSurf->LastVParameter();
IntPatch_SpecialPoints::
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, aTol,
AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, 0.0, aTol,
aStartPoint, anInfBound, aSupBound, aNewPoint,
IsReversed);
}
@@ -2878,7 +2915,9 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
if(sline->NbPoints() == 1)
{
flNextLine = Standard_True;
aFindex = aBindex;
if (aFindex < aBindex)
aFindex = aBindex;
//Go to the next part of aSSLine
//because we cannot create the line

View File

@@ -1432,8 +1432,32 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
theS2->IsVPeriodic()? theS2->VPeriod() : 0.0};
NCollection_List<gp_Pnt> aListOfCriticalPoints;
if (theS1->GetType() == GeomAbs_Cone)
{
aListOfCriticalPoints.Append(theS1->Cone().Apex());
}
else if (theS1->GetType() == GeomAbs_Sphere)
{
aListOfCriticalPoints.Append(theS1->Value(0.0, M_PI_2));
aListOfCriticalPoints.Append(theS1->Value(0.0, -M_PI_2));
}
if (theS2->GetType() == GeomAbs_Cone)
{
aListOfCriticalPoints.Append(theS2->Cone().Apex());
}
else if (theS2->GetType() == GeomAbs_Sphere)
{
aListOfCriticalPoints.Append(theS2->Value(0.0, M_PI_2));
aListOfCriticalPoints.Append(theS2->Value(0.0, -M_PI_2));
}
IntPatch_WLineTool::ExtendTwoWLines(slin, theS1, theS2, TolTang,
anArrOfPeriod, aBx1, aBx2);
anArrOfPeriod, aBx1, aBx2,
aListOfCriticalPoints);
}
}

View File

@@ -153,18 +153,18 @@ void IntPatch_Point::Dump() const {
Standard_Real u1,v1,u2,v2;
pt.Parameters(u1,v1,u2,v2);
printf("P(%15.10f,%15.10f,%15.10f) UV1(%15.10f,%15.10f) UV2(%15.10f,%15.10f) (Para:%15.10f)\n",
printf("P(%+10.20f,%+10.20f,%+10.20f) UV1(%+10.20f,%+10.20f) UV2(%+10.20f,%+10.20f) (Para:%+10.20f)\n",
(double)(pt.Value().X()),
(double)(pt.Value().Y()),
(double)(pt.Value().Z()),
(double)u1,(double)v1,(double)u2,(double)v2,(double)para);
if(onS1)
printf("*OnS1* par=%15.10f arc1=%10p", (double)prm1, (void*)arcS1.operator->());
printf("*OnS1* par=%+10.20f arc1=%10p", (double)prm1, (void*)arcS1.operator->());
if(vtxonS1)
printf(" *Vtx1* vtx1=%10p", (void*)vS1.operator->());
if(onS1 || vtxonS1) printf("\n");
if(onS2)
printf("*OnS2* par=%15.10f arc2=%10p", (double)prm2, (void*)arcS2.operator->());
printf("*OnS2* par=%+10.20f arc2=%10p", (double)prm2, (void*)arcS2.operator->());
if(vtxonS2)
printf(" *Vtx2* vtx2=%10p", (void*)vS2.operator->());
@@ -184,4 +184,6 @@ void IntPatch_Point::Dump() const {
}
cout<<endl;
}
cout << "\nToler = " << Tolerance();
cout << endl;
}

View File

@@ -222,7 +222,10 @@ private:
Standard_Real para;
Standard_Real tol;
Standard_Boolean tgt;
//TRUE if the point is in several intersection lines
Standard_Boolean mult;
Standard_Boolean onS1;
Standard_Boolean vtxonS1;
Handle(Adaptor3d_HVertex) vS1;

View File

@@ -119,8 +119,13 @@ Standard_Real IntPatch_PointLine::
const gp_Vec aCTan(aN1.Crossed(aN2));
const Standard_Real aSqMagnFDer = aCTan.SquareMagnitude();
if(aSqMagnFDer < aSqSmallValue)
if (aSqMagnFDer < 1.0e-8)
{
// Use 1.0e-4 (instead of aSmallValue) to provide
// stable computation between different platforms.
// See test bugs modalg_7 bug29807_sc01
return -1.0;
}
Standard_Real aDuS1 = 0.0, aDvS1 = 0.0, aDuS2 = 0.0, aDvS2 = 1.0;
@@ -160,7 +165,8 @@ Standard_Real IntPatch_PointLine::
const Standard_Real aDetSyst = aB*aB - aA*aC;
if(Abs(aDetSyst) < aSmallValue)
{//Indetermined system solution
{
//Undetermined system solution
return -1.0;
}

View File

@@ -16,6 +16,7 @@
#include <IntPatch_SpecialPoints.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <ElCLib.hxx>
#include <Extrema_ExtPS.hxx>
#include <Extrema_GenLocateExtPS.hxx>
#include <Geom_ConicalSurface.hxx>
@@ -35,10 +36,12 @@ class FuncPreciseSeam: public math_FunctionSetWithDerivatives
public:
FuncPreciseSeam(const Handle(Adaptor3d_HSurface)& theQSurf, // quadric
const Handle(Adaptor3d_HSurface)& thePSurf, // another surface
const Standard_Boolean isTheUSeam):
const Standard_Boolean isTheUSeam,
const Standard_Real theIsoParameter):
myQSurf(theQSurf),
myPSurf(thePSurf),
mySeamCoordInd(isTheUSeam? 1 : 0) // Defines, U- or V-seam is used
mySeamCoordInd(isTheUSeam? 1 : 0), // Defines, U- or V-seam is used
myIsoParameter(theIsoParameter)
{
};
@@ -58,7 +61,7 @@ public:
try
{
const Standard_Integer anIndX = theX.Lower(), anIndF = theF.Lower();
Standard_Real aUV[] = {0.0, 0.0};
Standard_Real aUV[] = {myIsoParameter, myIsoParameter};
aUV[mySeamCoordInd] = theX(anIndX+2);
const gp_Pnt aP1(myPSurf->Value(theX(anIndX), theX(anIndX+1)));
const gp_Pnt aP2(myQSurf->Value(aUV[0], aUV[1]));
@@ -81,7 +84,7 @@ public:
const Standard_Integer anIndX = theX.Lower(),
anIndRD = theD.LowerRow(),
anIndCD = theD.LowerCol();
Standard_Real aUV[] = {0.0, 0.0};
Standard_Real aUV[] = {myIsoParameter, myIsoParameter};
aUV[mySeamCoordInd] = theX(anIndX+2);
gp_Pnt aPt;
@@ -131,10 +134,30 @@ private:
const Handle(Adaptor3d_HSurface)& myQSurf;
const Handle(Adaptor3d_HSurface)& myPSurf;
// 1 for U-coordinate, 0 - for V one.
//! 1 for U-coordinate, 0 - for V one.
const Standard_Integer mySeamCoordInd;
//! Constant parameter of iso-line
const Standard_Real myIsoParameter;
};
//=======================================================================
//function : GetTangent
//purpose : Computes tangent having the given parameter.
// See calling method(s) for detailed information
//=======================================================================
static inline void GetTangent(const Standard_Real theConeSemiAngle,
const Standard_Real theParameter,
gp_XYZ& theResult)
{
const Standard_Real aW2 = theParameter*theParameter;
const Standard_Real aCosUn = (1.0 - aW2) / (1.0 + aW2);
const Standard_Real aSinUn = 2.0*theParameter / (1.0 + aW2);
const Standard_Real aTanA = Tan(theConeSemiAngle);
theResult.SetCoord(aTanA*aCosUn, aTanA*aSinUn, 1.0);
}
//=======================================================================
//function : IsPointOnSurface
//purpose : Checks if thePt is in theSurf (with given tolerance).
@@ -281,6 +304,7 @@ Standard_Boolean IntPatch_SpecialPoints::
const Handle(Adaptor3d_HSurface)& thePSurf,
const IntSurf_PntOn2S& theRefPt,
const Standard_Boolean theIsU,
const Standard_Real theIsoParameter,
const math_Vector& theToler,
const math_Vector& theInitPoint,
const math_Vector& theInfBound,
@@ -292,7 +316,7 @@ Standard_Boolean IntPatch_SpecialPoints::
IntSurf::SetPeriod(theIsReversed ? thePSurf : theQSurf,
theIsReversed ? theQSurf : thePSurf, anArrOfPeriod);
FuncPreciseSeam aF(theQSurf, thePSurf, theIsU);
FuncPreciseSeam aF(theQSurf, thePSurf, theIsU, theIsoParameter);
math_FunctionSetRoot aSRF(aF, theToler);
aSRF.Perform(aF, theInitPoint, theInfBound, theSupBound);
@@ -323,6 +347,432 @@ Standard_Boolean IntPatch_SpecialPoints::
return Standard_True;
}
//=======================================================================
//function : ProcessSphere
//purpose :
/*
The intersection point (including the pole)
must be satisfied to the following system:
\left\{\begin{matrix}
R*\cos (U_{q})*\cos (V_{q})=S_{x}(U_{s},V_{s})
R*\sin (U_{q})*\cos (V_{q})=S_{y}(U_{s},V_{s})
R*\sin (V_{q})=S_{z}(U_{s},V_{s})
\end{matrix}\right,
where
R is the radius of the sphere;
@S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf;
@U_{s}@ and @V_{s}@ are parameters on the parametric surface;
@U_{q}@ and @V_{q}@ are equal to theUquad and theVquad correspondingly.
Consequently (from first two equations),
\left\{\begin{matrix}
\cos (U_{q}) = \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}
\sin (U_{q}) = \frac{S_{y}(U_{s},V_{s})}{R*\cos (V_{q})}
\end{matrix}\right.
For pole,
V_{q}=\pm \pi /2 \Rightarrow \cos (V_{q}) = 0 (denominator is equal to 0).
Therefore, computation U_{q} directly is impossibly.
Let @V_{q}@ tends to @\pm \pi /2@.
Then (indeterminate form is evaluated in accordance of L'Hospital rule),
\cos (U_{q}) = \lim_{V_{q} \to (\pi /2-0)}
\frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}=
-\lim_{V_{q} \to (\pi /2-0)}
\frac{\frac{\partial S_{x}}
{\partial U_{s}}*\frac{\mathrm{d} U_{s}}
{\mathrm{d} V_{q}}+\frac{\partial S_{x}}
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}
{\mathrm{d} V_{q}}}{R*\sin (V_{q})} =
-\frac{1}{R}*\frac{\mathrm{d} U_{s}}
{\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
{\partial U_{s}}+\frac{\partial S_{x}}
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}
{\mathrm{d} U_{s}}) =
-\frac{1}{R}*\frac{\mathrm{d} V_{s}}
{\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
{\partial U_{s}}*\frac{\mathrm{d} U_{s}}
{\mathrm{d} V_{s}}+\frac{\partial S_{x}}
{\partial V_{s}}).
Analogicaly for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@).
Let mean, that
\cos (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \cos (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
\sin (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \sin (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
From the 3rd equation of the system, we obtain
\frac{\mathrm{d} (R*\sin (V_{q}))}{\mathrm{d} V_{q}} =
\frac{\mathrm{d} S_{z}(U_{s},V_{s})}{\mathrm{d} V_{q}}
or
R*\cos (V_{q}) = \frac{\partial S_{z}}{\partial U_{s}}*
\frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}}.
If @V_{q}=\pm \pi /2@, then
\frac{\partial S_{z}}{\partial U_{s}}*
\frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
{\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}} = 0.
Consequently, if @\frac{\partial S_{z}}{\partial U_{s}} \neq 0 @ then
\frac{\mathrm{d} U_{s}}{\mathrm{d} V_{s}} =
-\frac{\frac{\partial S_{z}}{\partial V_{s}}}
{\frac{\partial S_{z}}{\partial U_{s}}}.
If @ \frac{\partial S_{z}}{\partial V_{s}} \neq 0 @ then
\frac{\mathrm{d} V_{s}}{\mathrm{d} U_{s}} =
-\frac{\frac{\partial S_{z}}{\partial U_{s}}}
{\frac{\partial S_{z}}{\partial V_{s}}}
Cases, when @ \frac{\partial S_{z}}{\partial U_{s}} =
\frac{\partial S_{z}}{\partial V_{s}} = 0 @ are not consider here.
The reason is written below.
*/
//=======================================================================
Standard_Boolean IntPatch_SpecialPoints::ProcessSphere(const IntSurf_PntOn2S& thePtIso,
const gp_Vec& theDUofPSurf,
const gp_Vec& theDVofPSurf,
const Standard_Boolean theIsReversed,
const Standard_Real theVquad,
Standard_Real& theUquad,
Standard_Boolean& theIsIsoChoosen)
{
theIsIsoChoosen = Standard_False;
//Vector with {@ \cos (U_{q}) @, @ \sin (U_{q}) @} coordinates.
//Ask to pay attention to the fact that this vector is always normalized.
gp_Vec2d aV1;
if ((Abs(theDUofPSurf.Z()) < Precision::PConfusion()) &&
(Abs(theDVofPSurf.Z()) < Precision::PConfusion()))
{
//Example of this case is an intersection of a plane with a sphere
//when the plane tangents the sphere in some pole (i.e. only one
//intersection point, not line). In this case, U-coordinate of the
//sphere is undefined (can be realy anything).
//Another reason is that we have tangent zone around the pole
//(see bug #26576).
//Computation of correct value of theUquad is impossible.
//Therefore, (in order to return something) we will consider
//the intersection line goes along some isoline in neighborhood
//of the pole.
#ifdef INTPATCH_ADDSPECIALPOINTS_DEBUG
cout << "Cannot find UV-coordinate for quadric in the pole."
" See considered comment above. IntPatch_SpecialPoints.cxx,"
" ProcessSphere(...)" << endl;
#endif
Standard_Real aUIso = 0.0, aVIso = 0.0;
if (theIsReversed)
thePtIso.ParametersOnS2(aUIso, aVIso);
else
thePtIso.ParametersOnS1(aUIso, aVIso);
theUquad = aUIso;
theIsIsoChoosen = Standard_True;
}
else
{
if (Abs(theDUofPSurf.Z()) > Abs(theDVofPSurf.Z()))
{
const Standard_Real aDusDvs = theDVofPSurf.Z() / theDUofPSurf.Z();
aV1.SetCoord(theDUofPSurf.X()*aDusDvs - theDVofPSurf.X(),
theDUofPSurf.Y()*aDusDvs - theDVofPSurf.Y());
}
else
{
const Standard_Real aDvsDus = theDUofPSurf.Z() / theDVofPSurf.Z();
aV1.SetCoord(theDVofPSurf.X()*aDvsDus - theDUofPSurf.X(),
theDVofPSurf.Y()*aDvsDus - theDUofPSurf.Y());
}
aV1.Normalize();
if (Abs(aV1.X()) > Abs(aV1.Y()))
theUquad = Sign(asin(aV1.Y()), theVquad);
else
theUquad = Sign(acos(aV1.X()), theVquad);
}
return Standard_True;
}
//=======================================================================
//function : ProcessCone
//purpose :
/*
The intersection point (including the pole)
must be satisfied to the following system:
\left\{\begin {matrix}
(V_{q}\sin(a) + R)*\cos(U_{q})) = S_{x}(U_{s}, V_{s})\\
(V_{q}\sin(a) + R)*\sin(U_{q})) = S_{y}(U_{s}, V_{s})\\
V_{q}\cos(a) = S_{z}(U_{s}, V_{s})
\end {matrix}\right,
where
R is the radius of the cone;
a is its semi-angle;
@S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf;
@U_{s}@ and @V_{s}@ are parameters on the parametric surface;
@U_{q}@ and @V_{q}@ are equal to theUquad and theVquad correspondingly.
Consequently (from first two equations),
\left\{\begin{matrix}
\cos(U_{q})=\frac{S_{x}(U_{s},V_{s})}{(V_{q}\sin(a)+R)}\\
\sin(U_{q})=\frac{S_{y}(U_{s}, V_{s})}{(V_{q}\sin(a)+R)}
\end{matrix}\right.
For pole, the denominator of these two equations is equal to 0.
Therefore, computation U_{q} directly is impossibly.
Let @V_{q}@ tends to @\frac{-R}{\sin(a)})@.
Then (indeterminate form is evaluated in accordance of L'Hospital rule),
\cos (U_{q}) =
\lim_{V_{q} \to (\frac{-R}{\sin(a)})}\frac{S_{x}(U_{s},V_{s})}{(V_{q}\sin(a)+R)}=
\frac{1}{\sin(a)}* \lim_{V_{q} \to (\frac{-R}{\sin(a)})}\frac{dU_{s}}{dV_{q}}*
(\frac{\partial S_{x}}{\partial U_{s}}+\frac{\partial S_{x}}{\partial V_{s}}*
\frac{dV_{s}}{dU_{s}})=
\frac{1}{\sin(a)}* \lim_{V_{q} \to (\frac{-R}{\sin(a)})}\frac{dV_{s}}{dV_{q}}*
(\frac{\partial S_{x}}{\partial U_{s}}*
\frac{dU_{s}}{dV_{s}}+\frac{\partial S_{x}}{\partial V_{s}})
Analogically for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@).
After differentiating 3rd equation of the system, we will obtain
\cos(a)=\frac{dS_{z}}{dV_{q}}=\frac{dU_{s}}{dV_{q}}*
(\frac{\partial S_{z}}{\partial U_{s}}+\frac{\partial S_{z}}{\partial V_{s}}*
\frac{dV_{s}}{dU_{s}})
or
\frac{dU_{s}}{dV_{q}}=\frac{\cos(a)}{\frac{\partial S_{z}}{\partial U_{s}}+
\frac{\partial S_{z}}{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}
After substituting we will obtain
\cos (U_{q}) =
\cot(a)*\frac{\frac{\partial S_{x}}{\partial U_{s}}+\frac{\partial S_{x}}
{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}{\frac{\partial S_{z}}
{\partial U_{s}}+\frac{\partial S_{z}}{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}
\sin (U_{q}) =
\cot(a)*\frac{\frac{\partial S_{y}}{\partial U_{s}}+\frac{\partial S_{y}}
{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}{\frac{\partial S_{z}}
{\partial U_{s}}+\frac{\partial S_{z}}{\partial V_{s}}*\frac{dV_{s}}{dU_{s}}}
So, we have obtained vector with coordinates {@ \cos (U_{q}) @, @ \sin (U_{q}) @}.
Ask to pay attention to the fact that this vector is always normalized.
And after normalization this vector will have coordinates
{\cos (U_{q}), \sin (U_{q})} = {dS_{x}, dS_{y}}.Normalized().
It means that we have to compute a tangent to the intersection curve in
the cone apex point. After that, just take its X- and Y-coordinates.
However, we have to compute derivative @\frac{dV_{s}}{dU_{s}}@ in order
to compute this vector. In order to find this derivative, we use the
information about direction of tangent to the intersection curve.
This tangent will be directed along the cone generatrix obtained by intersection
of the cone with a plane tangent to 2nd (intersected) surface.
*/
//=======================================================================
Standard_Boolean IntPatch_SpecialPoints::ProcessCone(const IntSurf_PntOn2S& thePtIso,
const gp_Vec& theDUofPSurf,
const gp_Vec& theDVofPSurf,
const gp_Cone& theCone,
const Standard_Boolean theIsReversed,
Standard_Real& theUquad,
Standard_Boolean& theIsIsoChoosen)
{
theIsIsoChoosen = Standard_False;
// A plane tangent to 2nd (intersected) surface.
// Its normal.
const gp_XYZ aTgPlaneZ(theDUofPSurf.Crossed(theDVofPSurf).XYZ());
const Standard_Real aSqModTg = aTgPlaneZ.SquareModulus();
if (aSqModTg < Precision::SquareConfusion())
{
theIsIsoChoosen = Standard_True;
}
gp_XYZ aTgILine[2];
const Standard_Integer aNbTangent = !theIsIsoChoosen?
GetTangentToIntLineForCone(theCone.SemiAngle(),
aTgPlaneZ.Divided(Sqrt(aSqModTg)),
aTgILine) : 0;
if (aNbTangent == 0)
{
theIsIsoChoosen = Standard_True;
}
else
{
const Standard_Real aPeriod = M_PI + M_PI;
Standard_Real aUIso = 0.0, aVIso = 0.0;
if (theIsReversed)
thePtIso.ParametersOnS2(aUIso, aVIso);
else
thePtIso.ParametersOnS1(aUIso, aVIso);
aUIso = ElCLib::InPeriod(aUIso, 0.0, aPeriod);
// Sought U-parameter in the apex point
// For 2 possible parameters value,
// one will be chosen which is nearer
// to aUIso. Following variables will help to chose.
Standard_Real aMinDelta = RealLast();
for (Standard_Integer anIdx = 0; anIdx < aNbTangent; anIdx++)
{
// Vector {@\cos(a), \sin(a)@}
gp_Vec2d aVecCS(aTgILine[anIdx].X(), aTgILine[anIdx].Y());
const Standard_Real aSqMod = aVecCS.SquareMagnitude();
if (aSqMod < Precision::SquareConfusion())
{
theIsIsoChoosen = Standard_True;
break;
}
// Normalize
aVecCS.Divide(Sqrt(aSqMod));
// Angle in range [0, PI/2]
Standard_Real anUq = (Abs(aVecCS.X()) < Abs(aVecCS.Y())) ? ACos(Abs(aVecCS.X())) : ASin(Abs(aVecCS.Y()));
// Convert angles to the range [0, 2*PI]
if (aVecCS.Y() < 0.0)
{
if (aVecCS.X() > 0.0)
{
anUq = -anUq;
}
else
{
anUq += M_PI;
}
}
else if (aVecCS.X() < 0.0)
{
anUq = M_PI - anUq;
}
//Select the parameter the nearest to aUIso
anUq = ElCLib::InPeriod(anUq, 0.0, aPeriod);
Standard_Real aDelta = Abs(anUq - aUIso);
if (aDelta > M_PI)
aDelta = aPeriod - aDelta;
if (aDelta < aMinDelta)
{
aMinDelta = aDelta;
theUquad = anUq;
}
}
}
if (theIsIsoChoosen)
{
#ifdef INTPATCH_ADDSPECIALPOINTS_DEBUG
cout << "Cannot find UV-coordinate for quadric in the pole."
" IntPatch_AddSpecialPoints.cxx, ProcessCone(...)" << endl;
#endif
theIsIsoChoosen = Standard_True;
Standard_Real aUIso = 0.0, aVIso = 0.0;
if (theIsReversed)
thePtIso.ParametersOnS2(aUIso, aVIso);
else
thePtIso.ParametersOnS1(aUIso, aVIso);
theUquad = aUIso;
return Standard_True;
}
else
{
return Standard_True;
}
//return Standard_False;
}
//=======================================================================
//function : GetTangentToIntLineForCone
//purpose : The following conditions must be satisfied:
//1. The cone is represented in its canonical form.
//2. The plane goes through the cone apex and has the normal vector thePlnNormal.
//3. Vector thePlnNormal has already been normalized
/*
Let us enter the new coordinate system where the origin will be in the cone apex
and axes are the same as in World-Coordinate-System (WCS).
There the horizontal plane (which is parallel XY-plane) with the origin
(0, 0, 1) will intersect the cone by the circle with center (0, 0, 1),
direction {0, 0, 1} and radius tg(a) where a is the cone semi-angle.
Its equation will be
\left\{\begin{matrix}
x(U_{n}) = \tan(a)*\cos(U_{n}) = \tan(a)*\frac{1-\tan^{2}(U_{n}/2)}{1+\tan^{2}(U_{n}/2)}\\
y(U_{n}) = \tan(a)*\sin (U_{n}) = \tan(a)*\frac{2*\tan(U_{n}/2)}{1+\tan^{2}(U_{n}/2)}\\
z(U_{n}) = 1
\end{matrix}\right.
The given plane has (in this coordinate system) location (0, 0, 0) and
the same normal thePlnNormal=={nx,ny,nz}. Its equation is:
nx*x+ny*y+nz*z==0
After substitution circle's equation to the plane's equation
we will obtain a quadratic equation
aA*w^2 + 2*aB*w + aC = 0.
*/
//=======================================================================
Standard_Integer IntPatch_SpecialPoints::GetTangentToIntLineForCone(const Standard_Real theConeSemiAngle,
const gp_XYZ& thePlnNormal,
gp_XYZ theResult[2])
{
const Standard_Real aNullTol = Epsilon(1.0);
const Standard_Real aTanA = Tan(theConeSemiAngle);
const Standard_Real aA = thePlnNormal.Z() / aTanA - thePlnNormal.X();
const Standard_Real aB = thePlnNormal.Y();
const Standard_Real aC = thePlnNormal.Z() / aTanA + thePlnNormal.X();
if (Abs(aA) < aNullTol)
{
if (Abs(aB) > aNullTol)
{
//The plane goes along the cone generatrix.
GetTangent(theConeSemiAngle, -aC / (aB + aB), theResult[0]);
return 1;
}
//The cone and the plane have only one common point.
//It is the cone apex.
return 0;
}
//Discriminant of this equation is equal to
Standard_Real aDiscr = thePlnNormal.Z() / Sin(theConeSemiAngle);
aDiscr = 1.0 - aDiscr*aDiscr;
if (Abs(aDiscr) < aNullTol)
{
//The plane goes along the cone generatrix.
// Attention! Mathematically, this cond. is equivalent to
// above processed one (Abs(aA) < aNullTol && (Abs(aB) > aNullTol)).
// However, we separate this branch in order to eliminate numerical
// instability.
GetTangent(theConeSemiAngle, -aB / aA, theResult[0]);
return 1;
}
else if (aDiscr > 0.0)
{
const Standard_Real aRD = Sqrt(aDiscr);
GetTangent(theConeSemiAngle, (-aB+aRD)/aA, theResult[0]);
GetTangent(theConeSemiAngle, (-aB-aRD)/aA, theResult[1]);
return 2;
}
// We will never come here.
return 0;
}
//=======================================================================
//function : AddSingularPole
//purpose : theQSurf is the surface possibly containing special point,
@@ -333,22 +783,11 @@ Standard_Boolean IntPatch_SpecialPoints::
AddSingularPole(const Handle(Adaptor3d_HSurface)& theQSurf,
const Handle(Adaptor3d_HSurface)& thePSurf,
const IntSurf_PntOn2S& thePtIso,
const Standard_Real theTol,
IntPatch_Point& theVertex,
IntSurf_PntOn2S& theAddedPoint,
IntSurf_PntOn2S& theAddedPoint,
const Standard_Boolean theIsReversed,
const Standard_Boolean theIsReqRefCheck)
{
const Standard_Real aUpPeriod = thePSurf->IsUPeriodic() ? thePSurf->UPeriod() : 0.0;
const Standard_Real aUqPeriod = theQSurf->IsUPeriodic() ? theQSurf->UPeriod() : 0.0;
const Standard_Real aVpPeriod = thePSurf->IsVPeriodic() ? thePSurf->VPeriod() : 0.0;
const Standard_Real aVqPeriod = theQSurf->IsVPeriodic() ? theQSurf->VPeriod() : 0.0;
const Standard_Real anArrOfPeriod[4] = {theIsReversed? aUpPeriod : aUqPeriod,
theIsReversed? aVpPeriod : aVqPeriod,
theIsReversed? aUqPeriod : aUpPeriod,
theIsReversed? aVqPeriod : aVpPeriod};
//On parametric
Standard_Real aU0 = 0.0, aV0 = 0.0;
//aPQuad is Pole
@@ -379,13 +818,13 @@ Standard_Boolean IntPatch_SpecialPoints::
}
theQSurf->D0(aUquad, aVquad, aPQuad);
if (theIsReqRefCheck && (aPQuad.SquareDistance(theVertex.Value()) >= theTol*theTol))
const Standard_Real aTol = theVertex.Tolerance();
if (theIsReqRefCheck && (aPQuad.SquareDistance(theVertex.Value()) >= aTol*aTol))
{
return Standard_False;
}
if(!IsPointOnSurface(thePSurf, aPQuad, theTol, aP0, aU0, aV0))
if (!IsPointOnSurface(thePSurf, aPQuad, aTol, aP0, aU0, aV0))
{
return Standard_False;
}
@@ -398,25 +837,20 @@ Standard_Boolean IntPatch_SpecialPoints::
else
theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
Standard_Boolean isSame = Standard_False;
if (theAddedPoint.IsSame(theVertex.PntOn2S(), Precision::Confusion()))
{
isSame = Standard_True;
}
const Standard_Boolean isSame = theAddedPoint.IsSame(theVertex.PntOn2S(),
Precision::Confusion());
//Found pole does not exist in the Walking-line
//It must be added there (with correct 2D-parameters)
//2D-parameters of theparametric surface have already been found (aU0, aV0).
//2D-parameters of thePSurf surface have already been found (aU0, aV0).
//Let find 2D-parameters on the quadric.
//The algorithm depends on the type of the quadric. Here we consider a Sphere only.
//Analogical result can be made for another types (e.g. cone, but formulas will
//be different) in case of need.
//The algorithm depends on the type of the quadric.
//Here we consider a Sphere and cone only.
//First of all, we need in adjusting thePSurf in the coordinate system of the Sphere
//(in order to make the equation of the sphere maximal simple). However, as it will be
//First of all, we need in adjusting thePSurf in the coordinate system of the Sphere/Cone
//(in order to make its equation maximal simple). However, as it will be
//shown later, thePSurf is used in algorithm in order to get its derivatives.
//Therefore, for improving performance, transformation of these vectors is enough
//(there is no point in transformation of full surface).
@@ -439,146 +873,19 @@ Standard_Boolean IntPatch_SpecialPoints::
if(theQSurf->GetType() == GeomAbs_Sphere)
{
//The intersection point (including the pole)
//must be satisfied to the following system:
// \left\{\begin{matrix}
// R*\cos (U_{q})*\cos (V_{q})=S_{x}(U_{s},V_{s})
// R*\sin (U_{q})*\cos (V_{q})=S_{y}(U_{s},V_{s})
// R*\sin (V_{q})=S_{z}(U_{s},V_{s})
// \end{matrix}\right,
//where
// R is the radius of the sphere;
// @S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf;
// @U_{s}@ and @V_{s}@ are equal to aU0 and aV0 corespondingly;
// @U_{q}@ and @V_{q}@ are equal to aUquad and aVquad corespondingly.
//Consequently (from first two equations),
// \left\{\begin{matrix}
// \cos (U_{q}) = \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}
// \sin (U_{q}) = \frac{S_{y}(U_{s},V_{s})}{R*\cos (V_{q})}
// \end{matrix}\right.
//For pole,
// V_{q}=\pm \pi /2 \Rightarrow \cos (V_{q}) = 0 (denominator is equal to 0).
//Therefore, computation U_{q} directly is impossibly.
//
//Let @V_{q}@ tends to @\pm \pi /2@.
//Then (indeterminate form is evaluated in accordance of L'Hospital rule),
// \cos (U_{q}) = \lim_{V_{q} \to (\pi /2-0)}
// \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}=
// -\lim_{V_{q} \to (\pi /2-0)}
// \frac{\frac{\partial S_{x}}
// {\partial U_{s}}*\frac{\mathrm{d} U_{s}}
// {\mathrm{d} V_{q}}+\frac{\partial S_{x}}
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}
// {\mathrm{d} V_{q}}}{R*\sin (V_{q})} =
// -\frac{1}{R}*\frac{\mathrm{d} U_{s}}
// {\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
// {\partial U_{s}}+\frac{\partial S_{x}}
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}
// {\mathrm{d} U_{s}}) =
// -\frac{1}{R}*\frac{\mathrm{d} V_{s}}
// {\mathrm{d} V_{q}}*(\frac{\partial S_{x}}
// {\partial U_{s}}*\frac{\mathrm{d} U_{s}}
// {\mathrm{d} V_{s}}+\frac{\partial S_{x}}
// {\partial V_{s}}).
//Analogicaly for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@).
//Let mean, that
// \cos (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \cos (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
// \sin (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \sin (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
//From the 3rd equation of the system, we obtain
// \frac{\mathrm{d} (R*\sin (V_{q}))}{\mathrm{d} V_{q}} =
// \frac{\mathrm{d} S_{z}(U_{s},V_{s})}{\mathrm{d} V_{q}}
//or
// R*\cos (V_{q}) = \frac{\partial S_{z}}{\partial U_{s}}*
// \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}}.
//If @V_{q}=\pm \pi /2@, then
// \frac{\partial S_{z}}{\partial U_{s}}*
// \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
// {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}} = 0.
//Consequently, if @\frac{\partial S_{z}}{\partial U_{s}} \neq 0 @ then
// \frac{\mathrm{d} U_{s}}{\mathrm{d} V_{s}} =
// -\frac{\frac{\partial S_{z}}{\partial V_{s}}}
// {\frac{\partial S_{z}}{\partial U_{s}}}.
//If @ \frac{\partial S_{z}}{\partial V_{s}} \neq 0 @ then
// \frac{\mathrm{d} V_{s}}{\mathrm{d} U_{s}} =
// -\frac{\frac{\partial S_{z}}{\partial U_{s}}}
// {\frac{\partial S_{z}}{\partial V_{s}}}
//Cases, when @ \frac{\partial S_{z}}{\partial U_{s}} =
//\frac{\partial S_{z}}{\partial V_{s}} = 0 @ are not consider here.
//The reason is written below.
//Vector with {@ \cos (U_{q}) @, @ \sin (U_{q}) @} coordinates.
//Ask to pay attention to the fact that this vector is always normalyzed.
gp_Vec2d aV1;
if( (Abs(aVecDu.Z()) < Precision::PConfusion()) &&
(Abs(aVecDv.Z()) < Precision::PConfusion()))
if (!ProcessSphere(thePtIso, aVecDu, aVecDv, theIsReversed,
aVquad, aUquad, isIsoChoosen))
{
//Example of this case is an intersection of a plane with a sphere
//when the plane tangents the sphere in some pole (i.e. only one
//intersection point, not line). In this case, U-coordinate of the
//sphere is undefined (can be realy anything).
//Another reason is that we have tangent zone around the pole
//(see bug #26576).
//Computation of correct value of aUquad is impossible.
//Therefore, (in oreder to return something) we will consider
//the intersection line goes along some isoline in neighbourhood
//of the pole.
#ifdef INTPATCH_ADDSPECIALPOINTS_DEBUG
cout << "Cannot find UV-coordinate for quadric in the pole."
" See considered comment above. IntPatch_AddSpecialPoints.cxx,"
" AddSingularPole(...)" << endl;
#endif
Standard_Real aUIso = 0.0, aVIso = 0.0;
if(theIsReversed)
thePtIso.ParametersOnS2(aUIso, aVIso);
else
thePtIso.ParametersOnS1(aUIso, aVIso);
aUquad = aUIso;
isIsoChoosen = Standard_True;
}
else
{
if(Abs(aVecDu.Z()) > Abs(aVecDv.Z()))
{
const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z();
aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(),
aVecDu.Y()*aDusDvs - aVecDv.Y());
}
else
{
const Standard_Real aDvsDus = aVecDu.Z()/aVecDv.Z();
aV1.SetCoord( aVecDv.X()*aDvsDus - aVecDu.X(),
aVecDv.Y()*aDvsDus - aVecDu.Y());
}
aV1.Normalize();
if(Abs(aV1.X()) > Abs(aV1.Y()))
aUquad = Sign(asin(aV1.Y()), aVquad);
else
aUquad = Sign(acos(aV1.X()), aVquad);
return Standard_False;
}
}
else //if(theQSurf->GetType() == GeomAbs_Cone)
{
// This case is not processed. However,
// it can be done using the same algorithm
// as for sphere (formulas will be different).
return Standard_False;
if (!ProcessCone(thePtIso, aVecDu, aVecDv, theQSurf->Cone(),
theIsReversed, aUquad, isIsoChoosen))
{
return Standard_False;
}
}
if(theIsReversed)
@@ -594,6 +901,16 @@ Standard_Boolean IntPatch_SpecialPoints::
if (!isIsoChoosen)
{
Standard_Real anArrOfPeriod[4];
if (theIsReversed)
{
IntSurf::SetPeriod(thePSurf, theQSurf, anArrOfPeriod);
}
else
{
IntSurf::SetPeriod(theQSurf, thePSurf, anArrOfPeriod);
}
AdjustPointAndVertex(theVertex.PntOn2S(), anArrOfPeriod, theAddedPoint);
}
else
@@ -606,7 +923,32 @@ Standard_Boolean IntPatch_SpecialPoints::
//=======================================================================
//function : ContinueAfterSpecialPoint
//purpose :
//purpose : If the last point of the line is the pole of the quadric then
// the Walking-line has been broken in this point.
// However, new line must start from this point. Here we must
// find 2D-coordinates of "this new" point.
/*
The inters. line in the neighborhood of the Apex/Pole(s) can be
approximated by the intersection result of the Cone/Sphere with
the plane going through the Apex/Pole and being tangent to the
2nd intersected surface. This intersection result is well known.
In case of sphere, the inters. result is a circle.
If we go along this circle and across the Pole then U-parameter of
the sphere (@U_{q}@) will change to +/-PI.
In case of cone, the inters. result is two intersected lines (which
can be merged to one in a special case when the plane goes along
some generatrix of the cone). The direction of these lines
are computed by GetTangentToIntLineForCone(...) method).
When the real (not lines) inters. curve goes through the cone apex then
two variants are possible:
a) The tangent line to the inters. curve will be left. In this case
U-parameter of the cone (@U_{q}@) will be change to +/-PI.
b) Another line (as inters. result of cone + plane) will tangent
to the inters. curve. In this case @U_{q}@ must be recomputed.
*/
//=======================================================================
Standard_Boolean IntPatch_SpecialPoints::
ContinueAfterSpecialPoint(const Handle(Adaptor3d_HSurface)& theQSurf,
@@ -620,36 +962,63 @@ Standard_Boolean IntPatch_SpecialPoints::
if(theSPType == IntPatch_SPntNone)
return Standard_False;
//If the last point of the line is the pole of the quadric.
//In this case, Walking-line has been broken in this point.
//However, new line must start from this point. Here we must
//find its 2D-coordinates.
//For sphere and cone, some intersection point is satisfied to the system
// \cos(U_{q}) = S_{x}(U_{s},V_{s})/F(V_{q})
// \sin(U_{q}) = S_{y}(U_{s},V_{s})/F(V_{q})
//where
// @S_{x}@, @S_{y}@ are X and Y-coordinates of thePSurf;
// @U_{s}@ and @V_{s}@ are UV-parameters on thePSurf;
// @U_{q}@ and @V_{q}@ are UV-parameters on theQSurf;
// @F(V_{q}) @ is some function, which value independs on @U_{q}@
// (form of this function depends on the type of the quadric).
//When we go through the pole/apex, the function @F(V_{q}) @ changes sign.
//Therefore, some cases are possible, when only @\cos(U_{q}) @ or
//only @ \sin(U_{q}) @ change sign.
//Consequently, when the line goes throug the pole, @U_{q}@ can be
//changed on @\pi /2 @ (but not less).
if(theNewPoint.IsSame(theRefPt, Precision::Confusion(), theTol2D))
{
return Standard_False;
}
//Here, in case of pole/apex adding, we forbid "jumping" between two neighbor
//Walking-point with step greater than pi/4
if ((theSPType == IntPatch_SPntPole) && (theQSurf->GetType() == GeomAbs_Cone))
{
//Check if the condition b) is satisfied.
//Repeat the same steps as in
//IntPatch_SpecialPoints::AddSingularPole(...) method.
//On parametric
Standard_Real aU0 = 0.0, aV0 = 0.0;
//On quadric
Standard_Real aUquad = 0.0, aVquad = 0.0;
if (theIsReversed)
theNewPoint.Parameters(aU0, aV0, aUquad, aVquad);
else
theNewPoint.Parameters(aUquad, aVquad, aU0, aV0);
gp_Pnt aPtemp;
gp_Vec aVecDu, aVecDv;
thePSurf->D1(aU0, aV0, aPtemp, aVecDu, aVecDv);
//Transforms parametric surface in coordinate-system of the quadric
gp_Trsf aTr;
aTr.SetTransformation(theQSurf->Cone().Position());
//Derivatives of transformed thePSurf
aVecDu.Transform(aTr);
aVecDv.Transform(aTr);
Standard_Boolean isIsoChoosen = Standard_False;
ProcessCone(theRefPt, aVecDu, aVecDv, theQSurf->Cone(),
theIsReversed, aUquad, isIsoChoosen);
theNewPoint.SetValue(!theIsReversed, aUquad, aVquad);
}
//As it has already been said, in case of going through the Pole/Apex,
//U-parameter of the quadric surface will change to +/-PI. This rule has some
//exceptions:
//1. When 2nd surface has C0-continuity in the point common with the Apex/Pole.
// In this case, the tangent line to the intersection curve after the Apex/Pole
// must be totally recomputed according to the new derivatives of the 2nd surface.
// Currently, it is not implemented but will be able to be done after the
// corresponding demand.
//2. The inters. curve has C1 continuity but huge curvature in the point common with
// the Apex/Pole. Existing inters. algorithm does not allow putting many points
// near to the Apex/Pole in order to cover this "sharp" piece of the inters. curve.
// Therefore, we use adjusting U-parameter of the quadric surface with
// period PI/2 instead of 2PI. It does not have any mathematical idea
// but allows creating WLine with more or less uniform distributed points.
// In other words, we forbid "jumping" between two neighbor Walking-points
// with step greater than PI/4.
const Standard_Real aPeriod = (theSPType == IntPatch_SPntPole)? M_PI_2 : 2.0*M_PI;
const Standard_Real aUpPeriod = thePSurf->IsUPeriodic() ? thePSurf->UPeriod() : 0.0;

View File

@@ -24,6 +24,9 @@
#include <Standard_Handle.hxx>
class Adaptor3d_HSurface;
class gp_Cone;
class gp_Vec;
class gp_XYZ;
class IntPatch_Point;
class IntSurf_PntOn2S;
class math_Vector;
@@ -51,12 +54,18 @@ public:
//! theRefPt is used to correct adjusting parameters.
//! If theIsReversed is TRUE then theQSurf corresponds to the
//! second (otherwise, the first) surface while forming
//! intersection point IntSurf_PntOn2S.
//! intersection point IntSurf_PntOn2S.
//! All math_Vector-objects must be filled as follows:
//! [1] - U-parameter of thePSurf;
//! [2] - V-parameter of thePSurf;
//! [3] - U- (if V-isoline is considered) or V-parameter
//! (if U-isoline is considered) of theQSurf.
Standard_EXPORT static Standard_Boolean
AddPointOnUorVIso(const Handle(Adaptor3d_HSurface)& theQSurf,
const Handle(Adaptor3d_HSurface)& thePSurf,
const IntSurf_PntOn2S& theRefPt,
const Standard_Boolean theIsU,
const Standard_Real theIsoParameter,
const math_Vector& theToler,
const math_Vector& theInitPoint,
const math_Vector& theInfBound,
@@ -80,7 +89,6 @@ public:
AddSingularPole(const Handle(Adaptor3d_HSurface)& theQSurf,
const Handle(Adaptor3d_HSurface)& thePSurf,
const IntSurf_PntOn2S& thePtIso,
const Standard_Real theTol3d,
IntPatch_Point& theVertex,
IntSurf_PntOn2S& theAddedPoint,
const Standard_Boolean theIsReversed =
@@ -120,6 +128,39 @@ public:
const Standard_Real theArrPeriods[4],
IntSurf_PntOn2S &theNewPoint,
IntPatch_Point* const theVertex = 0);
protected:
//! Computes "special point" in the sphere
//! The parameter will be found in the range [0, 2*PI].
//! Therefore it must be adjusted to valid range by
//! the high-level algorithm
static Standard_EXPORT Standard_Boolean ProcessSphere(const IntSurf_PntOn2S& thePtIso,
const gp_Vec& theDUofPSurf,
const gp_Vec& theDVofPSurf,
const Standard_Boolean theIsReversed,
const Standard_Real theVquad,
Standard_Real& theUquad,
Standard_Boolean& theIsIsoChoosen);
//! Computes "special point" in the cone.
//! The parameter will be found in the range [0, 2*PI].
//! Therefore it must be adjusted to valid range by
//! the high-level algorithm.
static Standard_EXPORT Standard_Boolean ProcessCone(const IntSurf_PntOn2S& thePtIso,
const gp_Vec& theDUofPSurf,
const gp_Vec& theDVofPSurf,
const gp_Cone& theCone,
const Standard_Boolean theIsReversed,
Standard_Real& theUquad,
Standard_Boolean& theIsIsoChoosen);
//! Computes vector tangent to the intersection line in cone apex.
//! There exist not more than 2 tangent. They will be stores in theResult vector.
//! Returns the number of found tangents.
//! thePlnNormal is the normalized vector of the normal to the plane intersected the cone.
static Standard_EXPORT Standard_Integer GetTangentToIntLineForCone(const Standard_Real theConeSemiAngle,
const gp_XYZ& thePlnNormal,
gp_XYZ theResult[2]);
};
#endif // _IntPatch_AddSpecialPoints_HeaderFile

View File

@@ -41,7 +41,8 @@ enum IntPatchWT_WLsConnectionType
{
IntPatchWT_NotConnected,
IntPatchWT_Singular,
IntPatchWT_EachOther
IntPatchWT_Common,
IntPatchWT_ReqExtend
};
//=======================================================================
@@ -849,17 +850,23 @@ static IntPatchWT_WLsConnectionType
const Standard_Real* const theArrPeriods)
{
const Standard_Real aSqToler = theToler3D*theToler3D;
IntPatchWT_WLsConnectionType aRetVal = IntPatchWT_NotConnected;
if(theVec3.SquareMagnitude() <= aSqToler)
{
return IntPatchWT_NotConnected;
if ((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle))
{
return aRetVal;
}
else
{
aRetVal = IntPatchWT_Common;
}
}
if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
else if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
{
return IntPatchWT_NotConnected;
return aRetVal;
}
const gp_Pnt aPmid(0.5*(thePtWL1.Value().XYZ()+thePtWL2.Value().XYZ()));
@@ -973,7 +980,12 @@ static IntPatchWT_WLsConnectionType
return IntPatchWT_Singular;
}
return IntPatchWT_EachOther;
if (aRetVal == IntPatchWT_Common)
{
return IntPatchWT_Common;
}
return IntPatchWT_ReqExtend;
}
//=======================================================================
@@ -984,12 +996,47 @@ static IntPatchWT_WLsConnectionType
Standard_Boolean CheckArgumentsToJoin(const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2,
const IntSurf_PntOn2S& thePnt,
const gp_Pnt& theP1,
const gp_Pnt& theP2,
const gp_Pnt& theP3,
const Standard_Real theMinRad)
{
const Standard_Real aRad =
IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt);
const Standard_Real aRad =
IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt);
return (aRad > theMinRad);
if (aRad > theMinRad)
{
return Standard_True;
}
else if (aRad > 0.0)
{
return Standard_False;
}
// Curvature radius cannot be computed.
// Check smoothness of polygon.
// theP2
// *
// |
// |
// * o *
// theP1 O theP3
//Joining is enabled if two conditions are satisfied together:
// 1. Angle (theP1, theP2, theP3) is quite big;
// 2. Modulus of perpendicular (O->theP2) to the segment (theP1->theP3)
// is less than 0.01*<modulus of this segment>.
const gp_Vec aV12f(theP1, theP2), aV12l(theP2, theP3);
if (aV12f.Angle(aV12l) > IntPatch_WLineTool::myMaxConcatAngle)
return Standard_False;
const gp_Vec aV13(theP1, theP3);
const Standard_Real aSq13 = aV13.SquareMagnitude();
return (aV12f.CrossSquareMagnitude(aV13) < 1.0e-4*aSq13*aSq13);
}
//=======================================================================
@@ -1482,18 +1529,14 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
const Standard_Real aSqMinFDist = Min(aSqDistF, aSqDistL);
if (aSqMinFDist < Precision::SquareConfusion())
{
if (CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aMinRad))
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
isFirstConnected = Standard_True;
}
isFirstConnected = Standard_True;
}
}
@@ -1503,18 +1546,14 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
const Standard_Real aSqMinLDist = Min(aSqDistF, aSqDistL);
if (aSqMinLDist < Precision::SquareConfusion())
{
if (CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aMinRad))
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
isLastConnected = Standard_True;
}
isLastConnected = Standard_True;
}
}
@@ -1549,15 +1588,29 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
const Standard_Integer anIndexWL2 = isFirstConnected ? aListFC.First() : aListLC.First();
Handle(IntPatch_WLine) aWLine2(Handle(IntPatch_WLine)::DownCast(theSlin.Value(anIndexWL2)));
const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
aWLine1->ClearVertexes();
const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
if (isFirstConnected)
{
if (aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
const Standard_Real aSqDistF = aPntFWL1.Value().SquareDistance(aPntFWL2.Value());
const Standard_Real aSqDistL = aPntFWL1.Value().SquareDistance(aPntLWL2.Value());
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aPt1.Value(),
aPntFWL1.Value(), aPt2.Value(), aMinRad))
{
continue;
}
aWLine1->ClearVertexes();
if (isFM)
{
//First-First-connection
for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
@@ -1578,10 +1631,26 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
}
else //if (isLastConnected)
{
if (aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
const Standard_Real aSqDistF = aPntLWL1.Value().SquareDistance(aPntFWL2.Value());
const Standard_Real aSqDistL = aPntLWL1.Value().SquareDistance(aPntLWL2.Value());
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aPt1.Value(),
aPntFWL1.Value(), aPt2.Value(), aMinRad))
{
continue;
}
aWLine1->ClearVertexes();
if (isFM)
{
//Last-First connection
for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
{
const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
aWLine1->Curve()->Add(aPt);
@@ -1609,13 +1678,15 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
//purpose : Performs extending theWLine1 and theWLine2 through their
// respecting end point.
//=======================================================================
void IntPatch_WLineTool::ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2,
const Standard_Real theToler3D,
const Standard_Real* const theArrPeriods,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2)
void IntPatch_WLineTool::
ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2,
const Standard_Real theToler3D,
const Standard_Real* const theArrPeriods,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const NCollection_List<gp_Pnt>& theListOfCriticalPoints)
{
if(theSlin.Length() < 2)
return;
@@ -1677,6 +1748,46 @@ void IntPatch_WLineTool::ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
{
aCheckResult |= IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast;
}
if (!theListOfCriticalPoints.IsEmpty())
{
for (NCollection_List<gp_Pnt>::Iterator anItr(theListOfCriticalPoints);
anItr.More(); anItr.Next())
{
const gp_Pnt &aPt = anItr.Value();
if (!(aCheckResult & (IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast)))
{
if (aPt.SquareDistance(aPntFWL1.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast;
}
}
if (!(aCheckResult & (IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast)))
{
if (aPt.SquareDistance(aPntLWL1.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast;
}
}
if (!(aCheckResult & (IntPatchWT_DisFirstFirst | IntPatchWT_DisLastFirst)))
{
if (aPt.SquareDistance(aPntFWL2.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisFirstFirst | IntPatchWT_DisLastFirst;
}
}
if (!(aCheckResult & (IntPatchWT_DisFirstLast | IntPatchWT_DisLastLast)))
{
if (aPt.SquareDistance(aPntLWL2.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisFirstLast | IntPatchWT_DisLastLast;
}
}
}
}
}
if(aCheckResult == (IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast |

View File

@@ -18,6 +18,7 @@
#include <IntPatch_SequenceOfLine.hxx>
#include <IntPatch_WLine.hxx>
#include <NCollection_List.hxx>
class Adaptor3d_TopolTool;
@@ -49,29 +50,30 @@ public:
const Handle(Adaptor3d_TopolTool) &theDom1,
const Handle(Adaptor3d_TopolTool) &theDom2);
//! Joins all WLines from theSlin to one if it is possible and records
//! the result into theSlin again. Lines will be kept to be splitted if:
//! a) they are separated (has no common points);
//! b) resulted line (after joining) go through seam-edges or surface boundaries.
//!
//! In addition, if points in theSPnt lies at least in one of the line in theSlin,
//! this point will be deleted.
//! Joins all WLines from theSlin to one if it is possible and records
//! the result into theSlin again. Lines will be kept to be split if:
//! a) they are separated (has no common points);
//! b) resulted line (after joining) go through seam-edges or surface boundaries.
//!
//! In addition, if points in theSPnt lies at least in one of the line in theSlin,
//! this point will be deleted.
Standard_EXPORT static void JoinWLines(IntPatch_SequenceOfLine& theSlin,
IntPatch_SequenceOfPoint& theSPnt,
Handle(Adaptor3d_HSurface) theS1,
Handle(Adaptor3d_HSurface) theS2,
const Standard_Real theTol3D);
//! Extends every line from theSlin (if it is possible) to be started/finished
//! in strictly determined point (in the place of joint of two lines).
//! As result, some gaps between two lines will vanish.
//! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
//! to be computed as a result of intersection. Both theS1 and theS2
//! must be quadrics. Other cases are not supported.
//! theArrPeriods must be filled as follows (every value must not be negative;
//! if the surface is not periodic the period must be equal to 0.0 strictly):
//! {<U-period of 1st surface>, <V-period of 1st surface>,
//! <U-period of 2nd surface>, <V-period of 2nd surface>}.
//! Extends every line from theSlin (if it is possible) to be started/finished
//! in strictly determined point (in the place of joint of two lines).
//! As result, some gaps between two lines will vanish.
//! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
//! to be computed as a result of intersection. Both theS1 and theS2
//! must be quadrics. Other cases are not supported.
//! theArrPeriods must be filled as follows (every value must not be negative;
//! if the surface is not periodic the period must be equal to 0.0 strictly):
//! {<U-period of 1st surface>, <V-period of 1st surface>,
//! <U-period of 2nd surface>, <V-period of 2nd surface>}.
//! theListOfCriticalPoints must contain 3D-points where joining is disabled.
Standard_EXPORT static void
ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
const Handle(Adaptor3d_HSurface)& theS1,
@@ -79,7 +81,8 @@ public:
const Standard_Real theToler3D,
const Standard_Real* const theArrPeriods,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2);
const Bnd_Box2d& theBoxS2,
const NCollection_List<gp_Pnt>& theListOfCriticalPoints);
//! Max angle to concatenate two WLines to avoid result with C0-continuity
static const Standard_Real myMaxConcatAngle;

View File

@@ -225,14 +225,13 @@ void BoundedArc (const TheArc& A,
// Creer l echantillonage (math_FunctionSample ou classe heritant)
// Appel a math_FunctionAllRoots
Standard_Real EpsX = TheArcTool::Resolution(A,Precision::Confusion());
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@ La Tolerance est asociee a l arc ( Incoherence avec le cheminement )
//@@@ ( EpsX ~ 1e-5 et ResolutionU et V ~ 1e-9 )
//@@@ le vertex trouve ici n'est pas retrouve comme point d arret d une
//@@@ ligne de cheminement
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
EpsX = 0.0000000001;
Standard_Real EpsX = 1.e-10;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

View File

@@ -593,8 +593,8 @@ Standard_Integer IntTools_Context::ComputePE
{
gp_Pnt aPV = BRep_Tool::Pnt(aV);
aTolSum = aTolP1 + BRep_Tool::Tolerance(aV) + Precision::Confusion();
Standard_Real aDist1 = aP1.SquareDistance(aPV);
if (aDist1 < aDist && aDist1 < Square(aTolSum))
Standard_Real aDist1 = aP1.Distance(aPV);
if (aDist1 < aDist && aDist1 < aTolSum)
{
aDist = aDist1;
aT = BRep_Tool::Parameter(aV, aEFwd);

View File

@@ -352,11 +352,6 @@ Standard_Boolean IntTools_EdgeFace::CheckTouch
(const IntTools_CommonPrt& aCP,
Standard_Real& aTx)
{
if (myC.GetType() == GeomAbs_Line &&
myS.GetType() == GeomAbs_Plane) {
return Standard_False;
}
//
Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
Standard_Boolean theflag=Standard_False;
Standard_Integer aNbExt, iLower;

View File

@@ -43,6 +43,8 @@
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Wire.hxx>
#include <GeomLib.hxx>
#include <Poly.hxx>
#include <stdio.h>
@@ -85,7 +87,7 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
const Standard_Real TolUV)
{
Standard_Boolean WireIsNotEmpty, Ancienpnt3dinitialise, degenerated;
Standard_Integer nbpnts, firstpoint, NbEdges;
Standard_Integer firstpoint, NbEdges;
Standard_Integer iX, aNbs1, nbs, Avant, BadWire;
Standard_Real u, du, Tole, Tol, pfbid, plbid;
Standard_Real FlecheU, FlecheV, TolVertex1, TolVertex;
@@ -128,7 +130,6 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
for(; aExpF.More(); aExpF.Next()) {
const TopoDS_Wire& aW=*((TopoDS_Wire*)&aExpF.Current());
//
nbpnts = 0;
firstpoint =1;
FlecheU = 0.;
FlecheV = 0.;
@@ -264,7 +265,7 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
//-- and the last point saved in SeqPnt2d
//-- To to set the first point of the current
//-- afar from the last saved point
Avant = nbpnts;
Avant = SeqPnt2d.Length();
for(iX=firstpoint; iX<=aNbs1; iX++) {
Standard_Boolean IsRealCurve3d;
Standard_Integer ii;
@@ -282,7 +283,7 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
aDstX=RealLast();
if(degenerated==Standard_False) {
P3d=C3d.Value(u);
if(nbpnts>1) {
if(!SeqPnt2d.IsEmpty()) {
if(Ancienpnt3dinitialise) {
aDstX=P3d.SquareDistance(Ancienpnt3d);
}
@@ -308,11 +309,10 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
Ancienpnt3d=P3d;
Ancienpnt3dinitialise=Standard_True;
}
nbpnts++;
SeqPnt2d.Append(P2d);
}
//
ii=nbpnts;
ii= SeqPnt2d.Length();
if(ii>(Avant+4)) {
Standard_Real ul, dU, dV;
gp_Pnt2d Pp;
@@ -386,107 +386,38 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
}
//
else if(WireIsNotEmpty) {
TColgp_Array1OfPnt2d PClass(1,nbpnts);
gp_Pnt2d anInitPnt(0., 0.);
//
PClass.Init(anInitPnt);
if(nbpnts>3) {
Standard_Integer im2=nbpnts-2;
Standard_Integer im1=nbpnts-1;
Standard_Integer im0=1;
Standard_Real angle = 0.0;
Standard_Real aX0, aY0, aX1, aY1, aS;
//
aS=0.;
//
Standard_Integer iFlag=1;
//
PClass(im2)=SeqPnt2d.Value(im2);
PClass(im1)=SeqPnt2d.Value(im1);
PClass(nbpnts)=SeqPnt2d.Value(nbpnts);
Standard_Real aPer = 0.;
for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++, im2++)
{
if(im2>=nbpnts) im2=1;
if(im1>=nbpnts) im1=1;
PClass(ii)=SeqPnt2d.Value(ii);
//
const gp_Pnt2d& aP2D1=PClass(im1);
const gp_Pnt2d& aP2D0=PClass(im0);
//aP2D0 is next to aP2D1
aP2D0.Coord(aX0, aY0);
aP2D1.Coord(aX1, aY1);
aS=aS+(aY0+aY1)*(aX1-aX0);
aPer += aP2D1.Distance(aP2D0);
gp_Vec2d A(PClass(im2),PClass(im1));
gp_Vec2d B(PClass(im1),PClass(im0));
Standard_Real N = A.Magnitude() * B.Magnitude();
if(N>1e-16) {
Standard_Real a=A.Angle(B);
//
if (anIndexMap.IsBound(im1)) {
Standard_Integer anInd = anIndexMap.Find(im1);
const gp_Vec2d &aVPrev = aD1Prev.Value(anInd);
const gp_Vec2d &aVNext = aD1Next.Value(anInd);
Standard_Real aN = aVPrev.Magnitude() * aVNext.Magnitude();
if(aN > 1e-16) {
Standard_Real aDerivAngle, aAbsDA, aProduct, aPA;
//ifv 23.08.06
aPA=Precision::Angular();
aDerivAngle = aVPrev.Angle(aVNext);
aAbsDA=Abs(aDerivAngle);
if(aAbsDA <= aPA) {
aDerivAngle = 0.;
}
//
aProduct=aDerivAngle * a;
//
if(Abs(aAbsDA - M_PI) <= aPA) {
if (aProduct > 0.) {
aProduct=-aProduct;
}
}
//ifv 23.08.06 : if edges continuity > G1, |aDerivAngle| ~0,
//but can has wrong sign and causes condition aDerivAngle * a < 0.
//that is wrong in such situation
if (iFlag && aProduct < 0.) {
iFlag=0;
// Bad case.
angle = 0.;
}
}
}
angle+=a;
}
}//for(ii=1; ii<nbpnts; ii++,im0++,im1++,im2++) {
if (!iFlag) {
angle = 0.;
}
if (SeqPnt2d.Length() > 3)
{
#ifdef DEBUG_PCLASS_POLYGON
TColgp_Array1OfPnt2d PClass(1, nbpnts);
TColStd_Array1OfReal aKnots(1, nbpnts);
TColStd_Array1OfInteger aMults(1, nbpnts);
for (int i = 1; i <= nbpnts; i++)
{
aKnots(i) = i;
aMults(i) = 1;
PClass(ii) = SeqPnt2d.Value(ii);
}
aMults(1) = aMults(nbpnts) = 2;
Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1);
DrawTrSurf::Set("pol", aPol);
#endif
Standard_Real aS = 0.;
Standard_Real aPer = 0.;
Poly::PolygonProperties(SeqPnt2d, aS, aPer);
Standard_Real anExpThick = Max(2. * Abs(aS) / aPer, 1e-7);
Standard_Real aDefl = Max(FlecheU, FlecheV);
Standard_Real aDiscrDefl = Min(aDefl*0.1, anExpThick * 10.);
Standard_Boolean isChanged = Standard_False;
while (aDefl > anExpThick && aDiscrDefl > 1e-7)
{
// Deflection of the polygon is too much for this ratio of area and perimeter,
// and this might lead to self-intersections.
// Discretize the wire more tightly to eliminate the error.
firstpoint = 1;
isChanged = Standard_True;
SeqPnt2d.Clear();
FlecheU = 0.0;
FlecheV = 0.0;
@@ -532,41 +463,14 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
firstpoint = 2;
}
}
nbpnts = SeqPnt2d.Length();
PClass.Resize(1, nbpnts, Standard_False);
im1 = nbpnts - 1;
im0 = 1;
PClass(im1) = SeqPnt2d.Value(im1);
PClass(nbpnts) = SeqPnt2d.Value(nbpnts);
aS = 0.;
aPer = 0.;
for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++)
{
if (im1 >= nbpnts) im1 = 1;
PClass(ii) = SeqPnt2d.Value(ii);
aS += (PClass(im1).X() - PClass(im0).X())*(PClass(im0).Y() + PClass(im1).Y())*.5;
aPer += (PClass(im0).XY() - PClass(im1).XY()).Modulus();
}
#ifdef DEBUG_PCLASS_POLYGON
TColStd_Array1OfReal aKnots(1, nbpnts);
TColStd_Array1OfInteger aMults(1, nbpnts);
for (int i = 1; i <= nbpnts; i++)
{
aKnots(i) = i;
aMults(i) = 1;
}
aMults(1) = aMults(nbpnts) = 2;
Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1);
DrawTrSurf::Set("pol1", aPol);
#endif
anExpThick = Max(2. * Abs(aS) / aPer, 1e-7);
aDefl = Max(FlecheU, FlecheV);
aDiscrDefl = Min(aDiscrDefl * 0.1, anExpThick * 10.);
}
if(aS>0.){
myIsHole=Standard_False;
if (isChanged)
{
Poly::PolygonProperties(SeqPnt2d, aS, aPer);
}
//
if(FlecheU<Toluv)
@@ -575,25 +479,35 @@ void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
if(FlecheV<Toluv)
FlecheV = Toluv;
TabClass.Append((void *)new CSLib_Class2d(PClass,
TabClass.Append((void *)new CSLib_Class2d(SeqPnt2d,
FlecheU,
FlecheV,
Umin,Vmin,Umax,Vmax));
//
if((angle<2 && angle>-2)||(angle>10)||(angle<-10)) {
if(Abs(aS) < Precision::SquareConfusion()) {
BadWire=1;
TabOrien.Append(-1);
}
else {
TabOrien.Append((angle>0.0)? 1 : 0);
else
{
if (aS > 0.0)
{
myIsHole = Standard_False;
TabOrien.Append(1);
}
else
{
myIsHole = Standard_True;
TabOrien.Append(0);
}
}
}
else {
BadWire=1;
TabOrien.Append(-1);
TColgp_Array1OfPnt2d PPClass(1,2);
PPClass.Init(anInitPnt);
TabClass.Append((void *)new CSLib_Class2d(PPClass,
SeqPnt2d.Clear();
TabClass.Append((void *)new CSLib_Class2d(SeqPnt2d,
FlecheU,
FlecheV,
Umin,Vmin,Umax,Vmax));

View File

@@ -425,11 +425,9 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
Standard_Real umin, umax, vmin, vmax;
//
myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
CorrectPlaneBoundaries(umin, umax, vmin, vmax);
myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
//
myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
CorrectPlaneBoundaries(umin, umax, vmin, vmax);
myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
//
Standard_Real TolAng = 1.e-8;
@@ -524,9 +522,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
#ifdef INTTOOLS_FACEFACE_DEBUG
if(!myListOfPnts.IsEmpty()) {
char aBuff[10000];
const IntSurf_PntOn2S& aPt = myListOfPnts.First();
Standard_Real u1, v1, u2, v2;
aPt.Parameters(u1, v1, u2, v2);
Sprintf(aBuff,"bopcurves <face1 face2> -2d");
IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(myListOfPnts);

View File

@@ -34,6 +34,7 @@
myTS2=myT1;
myIsDone=Standard_False;
myIsSplittable=Standard_False;
myLength = 0.0;
}
//=======================================================================
//function : ~
@@ -59,6 +60,7 @@ void IntTools_ShrunkRange::SetData(const TopoDS_Edge& aE,
myT2=aT2;
myIsDone=Standard_False;
myIsSplittable=Standard_False;
myLength = 0.0;
}
//=======================================================================
//function : SetContext
@@ -178,9 +180,8 @@ void IntTools_ShrunkRange::Perform()
if (aPTolE > aPTolEMin) {
aPTolE = aPTolEMin;
}
Standard_Real anEdgeLength =
GCPnts_AbscissaPoint::Length(aBAC, myTS1, myTS2, aPTolE);
if (anEdgeLength < aDTol) {
myLength = GCPnts_AbscissaPoint::Length(aBAC, myTS1, myTS2, aPTolE);
if (myLength < aDTol) {
// micro edge
return;
}
@@ -192,11 +193,10 @@ void IntTools_ShrunkRange::Perform()
// for the edge to have possibility to be split at least once:
// 2*TolE - minimal diameter of tolerance sphere of splitting vertex
// 2*Precision::Confusion() - minimal length of the new edges
if (anEdgeLength > (2 * aTolE + 2 * aDTol)) {
if (myLength > (2 * aTolE + 2 * aDTol)) {
myIsSplittable = Standard_True;
}
//
// build bounding box for the edge on the shrunk range
BndLib_Add3dCurve::Add(aBAC, myTS1, myTS2,
aTolE + aDTol, myBndBox);
BndLib_Add3dCurve::Add(aBAC, myTS1, myTS2, aTolE + aDTol, myBndBox);
}

View File

@@ -74,6 +74,9 @@ Standard_EXPORT virtual ~IntTools_ShrunkRange();
return myIsSplittable;
}
//! Returns the length of the edge if computed.
Standard_Real Length() const { return myLength; }
protected:
TopoDS_Edge myEdge;
@@ -87,6 +90,7 @@ protected:
Handle(IntTools_Context) myCtx;
Standard_Boolean myIsDone;
Standard_Boolean myIsSplittable;
Standard_Real myLength;
private:

View File

@@ -370,6 +370,9 @@ public:
const TheItemType& operator() (const Standard_Integer theIndex) const
{ return Value (theIndex); }
//! operator[] - alias to Value
const TheItemType& operator[] (Standard_Integer theIndex) const { return Value (theIndex); }
//! Variable value access
TheItemType& ChangeValue (const Standard_Integer theIndex)
{
@@ -381,6 +384,9 @@ public:
TheItemType& operator() (const Standard_Integer theIndex)
{ return ChangeValue (theIndex); }
//! operator[] - alias to ChangeValue
TheItemType& operator[] (Standard_Integer theIndex) { return ChangeValue (theIndex); }
//! Set value
void SetValue (const Standard_Integer theIndex,
const TheItemType& theItem)

View File

@@ -238,6 +238,9 @@ public: //! @name public methods
return Value (theIndex);
}
//! Operator[] - query the const value
const TheItemType& operator[] (Standard_Integer theIndex) const { return Value (theIndex); }
const TheItemType& Value (const Standard_Integer theIndex) const
{
return *(const TheItemType* )findV (theIndex);
@@ -273,6 +276,9 @@ public: //! @name public methods
return ChangeValue (theIndex);
}
//! Operator[] - query the value
TheItemType& operator[] ( Standard_Integer theIndex) { return ChangeValue (theIndex); }
TheItemType& ChangeValue (const Standard_Integer theIndex)
{
return *(TheItemType* )findV (theIndex);

View File

@@ -20,12 +20,13 @@
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Poly_ListOfTriangulation.hxx>
#include <Standard_OStream.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_IStream.hxx>
#include <Standard_Real.hxx>
#include <TColgp_SequenceOfPnt2d.hxx>
class Poly_Triangulation;
class Poly_Polygon3D;
class Poly_Polygon2D;
@@ -125,6 +126,48 @@ public:
Standard_EXPORT static Standard_Real PointOnTriangle (const gp_XY& P1, const gp_XY& P2, const gp_XY& P3, const gp_XY& P, gp_XY& UV);
//! Returns area and perimeter of 2D-polygon given by its vertices.
//! theArea will be negative if the polygon is bypassed clockwise
//! and will be positive, otherwise. thePerimeter will always be positive.
//!
//! ATTENTION!!!
//! The container theSeqPnts of 2D-points gp_Pnt2d must have definition
//! for following methods: Length(), Lower(), Upper() and Value(Standard_Integer)
//! (e.g. it can be either NCollection_Sequence<gp_Pnt2d> or
//! NCollection_Array1<gp_Pnt2d>).
template <class TypeSequencePnts>
Standard_EXPORT static
Standard_Boolean PolygonProperties(const TypeSequencePnts& theSeqPnts,
Standard_Real& theArea,
Standard_Real& thePerimeter)
{
if (theSeqPnts.Length() < 2)
{
theArea = thePerimeter = 0.0;
return Standard_True;
}
Standard_Integer aStartIndex = theSeqPnts.Lower();
const gp_XY &aRefPnt = theSeqPnts.Value(aStartIndex++).XY();
gp_XY aPrevPt = theSeqPnts.Value(aStartIndex++).XY() - aRefPnt, aCurrPt;
theArea = 0.0;
thePerimeter = aPrevPt.Modulus();
for (Standard_Integer i = aStartIndex; i <= theSeqPnts.Upper(); i++)
{
aCurrPt = theSeqPnts.Value(i).XY() - aRefPnt;
const Standard_Real aDelta = aPrevPt.Crossed(aCurrPt);
theArea += aDelta;
thePerimeter += (aPrevPt - aCurrPt).Modulus();
aPrevPt = aCurrPt;
}
thePerimeter += aPrevPt.Modulus();
theArea *= 0.5;
return Standard_True;
}
protected:

View File

@@ -1534,25 +1534,6 @@ static Standard_Integer OCC24271 (Draw_Interpretor& di,
#include <GeomInt_IntSS.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Standard_ErrorHandler.hxx>
//=======================================================================
//function : OCC23972
//purpose :
//=======================================================================
static void DoGeomIntSSTest (const Handle(Geom_Surface)& theSurf1,
const Handle(Geom_Surface)& theSurf2,
const Standard_Integer theNbSol,
Draw_Interpretor& di)
{
try {
OCC_CATCH_SIGNALS
GeomInt_IntSS anInter;
anInter.Perform (theSurf1, theSurf2, Precision::Confusion(), Standard_True);
QVERIFY (anInter.IsDone());
QCOMPARE (anInter.NbLines(), theNbSol);
} catch (...) {
QVERIFY (Standard_False);
}
}
namespace {
static Handle(Geom_ConicalSurface) CreateCone (const gp_Pnt& theLoc,
@@ -1569,28 +1550,30 @@ namespace {
}
}
static Standard_Integer OCC23972 (Draw_Interpretor& di,Standard_Integer n, const char**)
static Standard_Integer OCC23972(Draw_Interpretor& /*theDI*/,
Standard_Integer theNArg, const char** theArgs)
{
if (n != 1) return 1;
if (theNArg != 3) return 1;
//process specific cones, cannot read them from files because due to rounding the original error
//in math_FunctionRoots gets hidden
Handle(Geom_Surface) aS1 = CreateCone (
gp_Pnt (123.694345356663, 789.9, 68.15),
gp_Dir (-1, 3.48029791472957e-016, -8.41302743359754e-017),
gp_Dir (-3.48029791472957e-016, -1, -3.17572289932207e-016),
3.28206830417112,
0.780868809443031,
0.624695047554424);
Handle(Geom_Surface) aS2 = CreateCone (
gp_Pnt (123.694345356663, 784.9, 68.15),
gp_Dir (-1, -2.5209507537117e-016, -1.49772808948866e-016),
gp_Dir (1.49772808948866e-016, 3.17572289932207e-016, -1),
3.28206830417112,
0.780868809443031,
0.624695047554424);
//process specific cones, cannot read them from files because
//due to rounding the original error in math_FunctionRoots gets hidden
const Handle(Geom_Surface) aS1 = CreateCone(
gp_Pnt(123.694345356663, 789.9, 68.15),
gp_Dir(-1, 3.48029791472957e-016, -8.41302743359754e-017),
gp_Dir(-3.48029791472957e-016, -1, -3.17572289932207e-016),
3.28206830417112,
0.780868809443031,
0.624695047554424);
const Handle(Geom_Surface) aS2 = CreateCone(
gp_Pnt(123.694345356663, 784.9, 68.15),
gp_Dir(-1, -2.5209507537117e-016, -1.49772808948866e-016),
gp_Dir(1.49772808948866e-016, 3.17572289932207e-016, -1),
3.28206830417112,
0.780868809443031,
0.624695047554424);
DoGeomIntSSTest (aS1, aS2, 2, di);
DrawTrSurf::Set(theArgs[1], aS1);
DrawTrSurf::Set(theArgs[2], aS2);
return 0;
}
@@ -4957,95 +4940,6 @@ static Standard_Integer OCC27048(Draw_Interpretor& theDI, Standard_Integer theAr
return 0;
}
//========================================================================
//function : OCC27065
//purpose : Tests overloaded method "Generated" of BRepOffsetAPI_MakePipe
//========================================================================
static Standard_Integer OCC27065(Draw_Interpretor& di,
Standard_Integer n, const char** a)
{
if (n < 3) return 1;
BRep_Builder BB;
TopoDS_Shape SpineShape = DBRep::Get(a[1],TopAbs_WIRE);
if ( SpineShape.IsNull()) return 1;
TopoDS_Wire Spine = TopoDS::Wire(SpineShape);
TopoDS_Shape Profile = DBRep::Get(a[2]);
if ( Profile.IsNull()) return 1;
BRepOffsetAPI_MakePipe aPipeBuilder(Spine, Profile);
if (!aPipeBuilder.IsDone())
{
di << "Error: failed to create pipe\n";
return 1;
}
TopExp_Explorer Explo(Profile, TopAbs_SHELL);
TopoDS_Shape aShape;
TopTools_ListIteratorOfListOfShape itl;
if (Explo.More())
{
aShape = Explo.Current();
TopoDS_Compound res1;
BB.MakeCompound(res1);
itl.Initialize(aPipeBuilder.Generated(aShape));
for (; itl.More(); itl.Next())
BB.Add(res1, itl.Value());
DBRep::Set("res_shell", res1);
}
Explo.Init(Profile, TopAbs_FACE);
if (Explo.More())
{
aShape = Explo.Current();
TopoDS_Compound res2;
BB.MakeCompound(res2);
itl.Initialize(aPipeBuilder.Generated(aShape));
for (; itl.More(); itl.Next())
BB.Add(res2, itl.Value());
DBRep::Set("res_face", res2);
}
Explo.Init(Profile, TopAbs_WIRE);
if (Explo.More())
{
aShape = Explo.Current();
TopoDS_Compound res3;
BB.MakeCompound(res3);
itl.Initialize(aPipeBuilder.Generated(aShape));
for (; itl.More(); itl.Next())
BB.Add(res3, itl.Value());
DBRep::Set("res_wire", res3);
}
Explo.Init(Profile, TopAbs_EDGE);
if (Explo.More())
{
aShape = Explo.Current();
TopoDS_Compound res4;
BB.MakeCompound(res4);
itl.Initialize(aPipeBuilder.Generated(aShape));
for (; itl.More(); itl.Next())
BB.Add(res4, itl.Value());
DBRep::Set("res_edge", res4);
}
Explo.Init(Profile, TopAbs_VERTEX);
if (Explo.More())
{
aShape = Explo.Current();
TopoDS_Compound res5;
BB.MakeCompound(res5);
itl.Initialize(aPipeBuilder.Generated(aShape));
for (; itl.More(); itl.Next())
BB.Add(res5, itl.Value());
DBRep::Set("res_vertex", res5);
}
return 0;
}
//========================================================================
//function : OCC27318
//purpose : Creates a box that is not listed in map of AIS objects of ViewerTest
@@ -5492,10 +5386,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
"OCC27048 surf U V N\nCalculate value of surface N times in the point (U, V)",
__FILE__, OCC27048, group);
theCommands.Add ("OCC27065",
"OCC27065 spine profile",
__FILE__, OCC27065, group);
theCommands.Add ("OCC27318",
"OCC27318: Creates a box that is not listed in map of AIS objects of ViewerTest",
__FILE__, OCC27318, group);

View File

@@ -2889,6 +2889,56 @@ static Standard_Integer OCC29531(Draw_Interpretor&, Standard_Integer, const char
return 0;
}
//=======================================================================
//function : OCC29807
//purpose :
//=======================================================================
#include <GeomAdaptor_HSurface.hxx>
#include <IntPatch_PointLine.hxx>
#include <IntSurf_PntOn2S.hxx>
static Standard_Integer OCC29807(Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgV)
{
if (theNArg != 7)
{
theDI << "Use: " << theArgV[0] << "surface1 surface2 u1 v1 u2 v2\n";
return 1;
}
const Handle(Geom_Surface) aS1 = DrawTrSurf::GetSurface(theArgV[1]);
const Handle(Geom_Surface) aS2 = DrawTrSurf::GetSurface(theArgV[2]);
if (aS1.IsNull() || aS2.IsNull())
{
theDI << "Error. Null surface is not supported.\n";
return 1;
}
const Standard_Real aU1 = Draw::Atof(theArgV[3]);
const Standard_Real aV1 = Draw::Atof(theArgV[4]);
const Standard_Real aU2 = Draw::Atof(theArgV[5]);
const Standard_Real aV2 = Draw::Atof(theArgV[6]);
const Handle(GeomAdaptor_HSurface) anAS1 = new GeomAdaptor_HSurface(aS1);
const Handle(GeomAdaptor_HSurface) anAS2 = new GeomAdaptor_HSurface(aS2);
const gp_Pnt aP1 = anAS1->Value(aU1, aV1);
const gp_Pnt aP2 = anAS2->Value(aU2, aV2);
if (aP1.SquareDistance(aP2) > Precision::SquareConfusion())
{
theDI << "Error. True intersection point must be specified. "
"Please check parameters: u1 v1 u2 v2.\n";
return 1;
}
IntSurf_PntOn2S aPOn2S;
aPOn2S.SetValue(0.5*(aP1.XYZ() + aP2.XYZ()), aU1, aV1, aU2, aV2);
const Standard_Real aCurvatureRadius = IntPatch_PointLine::CurvatureRadiusOfIntersLine(anAS1, anAS2, aPOn2S);
theDI << "Radius of curvature is " << aCurvatureRadius << "\n";
return 0;
}
void QABugs::Commands_20(Draw_Interpretor& theCommands) {
const char *group = "QABugs";
@@ -2925,5 +2975,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
theCommands.Add("OCC29531", "OCC29531 <step file name>", __FILE__, OCC29531, group);
theCommands.Add ("OCC29064", "OCC29064: test memory usage by copying empty maps", __FILE__, OCC29064, group);
theCommands.Add("OCC29807", "OCC29807 surface1 surface2 u1 v1 u2 v2", __FILE__, OCC29807, group);
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -191,18 +191,20 @@ void TDataStd_RealArray::ChangeArray(const Handle(TColStd_HArray1OfReal)& newArr
Standard_Boolean aDimEqual = Standard_False;
Standard_Integer i;
if (Lower() == aLower && Upper() == anUpper ) {
aDimEqual = Standard_True;
Standard_Boolean isEqual = Standard_True;
if(isCheckItems) {
for(i = aLower; i <= anUpper; i++) {
if(myValue->Value(i) != newArray->Value(i)) {
isEqual = Standard_False;
break;
if (!myValue.IsNull()) {
if (Lower() == aLower && Upper() == anUpper ) {
aDimEqual = Standard_True;
Standard_Boolean isEqual = Standard_True;
if(isCheckItems) {
for(i = aLower; i <= anUpper; i++) {
if(myValue->Value(i) != newArray->Value(i)) {
isEqual = Standard_False;
break;
}
}
if(isEqual)
return;
}
if(isEqual)
return;
}
}

View File

@@ -35,7 +35,7 @@ class gp_Vec;
//! Defines an infinite conical surface.
//! A cone is defined by its half-angle at the apex and
//! A cone is defined by its half-angle (can be negative) at the apex and
//! positioned in space with a coordinate system (a gp_Ax3
//! object) and a "reference radius" where:
//! - the "main Axis" of the coordinate system is the axis of revolution of the cone,
@@ -76,12 +76,13 @@ public:
//! Creates an infinite conical surface. A3 locates the cone
//! in the space and defines the reference plane of the surface.
//! Ang is the conical surface semi-angle between 0 and PI/2 radians.
//! Ang is the conical surface semi-angle. Its absolute value is in range
//! ]0, PI/2[.
//! Radius is the radius of the circle in the reference plane of
//! the cone.
//! Raises ConstructionError
//! . if Radius is lower than 0.0
//! . Ang < Resolution from gp or Ang >= (PI/2) - Resolution.
//! * if Radius is lower than 0.0
//! * Abs(Ang) < Resolution from gp or Abs(Ang) >= (PI/2) - Resolution.
gp_Cone(const gp_Ax3& A3, const Standard_Real Ang, const Standard_Real Radius);
//! Changes the symmetry axis of the cone. Raises ConstructionError
@@ -105,8 +106,9 @@ public:
//! Changes the semi-angle of the cone.
//! Ang is the conical surface semi-angle ]0,PI/2[.
//! Raises ConstructionError if Ang < Resolution from gp or Ang >= PI/2 - Resolution
//! Semi-angle can be negative. Its absolute value
//! Abs(Ang) is in range ]0,PI/2[.
//! Raises ConstructionError if Abs(Ang) < Resolution from gp or Abs(Ang) >= PI/2 - Resolution
void SetSemiAngle (const Standard_Real Ang);
@@ -146,6 +148,7 @@ public:
Standard_Real RefRadius() const;
//! Returns the half-angle at the apex of this cone.
//! Attention! Semi-angle can be negative.
Standard_Real SemiAngle() const;
//! Returns the XAxis of the reference plane.

View File

@@ -1,10 +1,44 @@
# Original bug : buc60127
# Date : 18mar98
puts "TODO #22911 ALL: Error : The command is not valid. The area is 0."
restore [locate_data_file buc60127-part.rle] part
restore [locate_data_file buc60127-tool.rle] tool
# fix the part shape
explode part f
# fix inner cylinder
mksurface c_in part_1
trim c_in c_in
mkface f_in c_in 0 2*pi 0 150
# fix side faces
mksurface s1 part_3
mksurface s2 part_4
mkface f1 s1 -10 10 -10 10
mkface f2 s2 -10 10 -10 10
# fix solid
mkvolume r part_2 f_in f1 f2
# find the outher solid - the one containing the outer cylinder (part_2 face)
foreach s [explode r so] {
set found 0
foreach f [explode $s f] {
if {[regexp "same shapes" [compare part_2 $f]]} {
copy $s part
set found 1
break
}
}
if {$found} {
break
}
}
bcut result part tool
checkprops result -s 0
checkshape result
checkprops result -s 5382.41 -v 2643.38
checknbshapes result -wire 14 -face 11 -shell 1 -solid 1
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -6,5 +6,8 @@ restore [locate_data_file pro10658b.rle] b
bfuse result a b
checkprops result -s 8636.79
checkview -display result -2d -otherwise { a b } -s -path ${imagedir}/${test_image}.png
checkshape result
checkprops result -s 8231.06 -v 30472.5
checknbshapes result -wire 9 -face 9 -shell 1 -solid 1
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,9 +1,11 @@
# pro10658
puts "TODO ALL: Error : The area of result shape is"
restore [locate_data_file CTO900_pro10658a.rle] a
restore [locate_data_file pro10658b.rle] b
bfuse result a b
checkprops result -s 8231.06
checkview -display result -2d -otherwise { a b } -s -path ${imagedir}/${test_image}.png
checkshape result
checkprops result -s 8231.06 -v 30472.5
checknbshapes result -wire 9 -face 9 -shell 1 -solid 1
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -3,6 +3,6 @@ plane p 0 0 0 1 0 0
mkface f p
bsection result a f
checkprops result -l 18981.2
checkprops result -l 20674.3
checksection result
checkview -display result -2d -otherwise { a f } -l -path ${imagedir}/${test_image}.png

View File

@@ -8,6 +8,6 @@ restore [locate_data_file ger61235b.brep] object
bsection result object tool
checkprops result -l 11.8242
checkprops result -l 16.4762
checksection result
checkview -display result -2d -otherwise { object tool } -l -path ${imagedir}/${test_image}.png

View File

@@ -14,7 +14,7 @@ compound feature1 feature2 feature3 feature4 gap
removefeatures res1 s feature1
checkshape res1
checkprops res1 -s 2387.42 -v 1060.96 -deps 1.e-7
checknbshapes res1 -vertex 68 -edge 102 -wire 36 -face 36 -shell 1 -solid 1 -t
checknbshapes res1 -vertex 66 -edge 99 -wire 35 -face 35 -shell 1 -solid 1 -t
CheckIsFeatureRemoved feature1 {v e f}
removefeatures res3 s feature1 feature2
@@ -27,19 +27,19 @@ CheckIsFeatureRemoved feature2 {e f}
removefeatures res4 s feature3
checkshape res4
checkprops res4 -s 2387.67 -v 1060.68 -deps 1.e-7
checknbshapes res4 -vertex 70 -edge 105 -wire 37 -face 37 -shell 1 -solid 1 -t
checknbshapes res4 -vertex 67 -edge 100 -wire 35 -face 35 -shell 1 -solid 1 -t
CheckIsFeatureRemoved feature3 {v e f}
removefeatures res5 s feature4
checkshape res5
checkprops res5 -s 2387.67 -v 1060.68 -deps 1.e-7
checknbshapes res5 -vertex 70 -edge 105 -wire 37 -face 37 -shell 1 -solid 1 -t
checkprops res5 -s 2387.67 -v 1060.67 -deps 1.e-7
checknbshapes res5 -vertex 67 -edge 100 -wire 35 -face 35 -shell 1 -solid 1 -t
CheckIsFeatureRemoved feature4 {v e f}
removefeatures res6 s feature3 feature4
checkshape res6
checkprops res6 -s 2387.89 -v 1060.71 -deps 1.e-7
checknbshapes res6 -vertex 68 -edge 102 -wire 36 -face 36 -shell 1 -solid 1 -t
checknbshapes res6 -vertex 65 -edge 97 -wire 34 -face 34 -shell 1 -solid 1 -t
CheckIsFeatureRemoved feature3 {v e f}
CheckIsFeatureRemoved feature4 {v e f}

View File

@@ -12,17 +12,17 @@ compound feature1 feature2 gap
removefeatures res1 s feature1
checkshape res1
checkprops res1 -s 2387.38 -v 1060.67 -deps 1.e-7
checknbshapes res1 -vertex 62 -edge 93 -wire 33 -face 33 -shell 1 -solid 1
checknbshapes res1 -vertex 60 -edge 89 -wire 31 -face 31 -shell 1 -solid 1
CheckIsFeatureRemoved feature1 {v e f}
removefeatures res2 s feature2
checkshape res2
checkprops res2 -s 2387.17 -v 1060.75 -deps 1.e-7
checknbshapes res2 -vertex 62 -edge 93 -wire 35 -face 34 -shell 1 -solid 1
checknbshapes res2 -vertex 60 -edge 89 -wire 33 -face 32 -shell 1 -solid 1
CheckIsFeatureRemoved feature2 {v e f}
removefeatures res3 s gap
checkshape res3
checkprops res3 -s 2386.99 -v 1060.79 -deps 1.e-7
checknbshapes res3 -vertex 54 -edge 81 -wire 29 -face 29 -shell 1 -solid 1
checknbshapes res3 -vertex 52 -edge 77 -wire 27 -face 27 -shell 1 -solid 1
CheckIsFeatureRemoved gap {v e f}

View File

@@ -10,5 +10,5 @@ compound s_37 s_26 s_27 s_28 gap
removefeatures res s gap
checkshape res
checkprops res -s 2387.07 -v 1060.76 -deps 1.e-7
checknbshapes res -vertex 64 -edge 96 -wire 34 -face 34 -shell 1 -solid 1
checknbshapes res -vertex 62 -edge 92 -wire 32 -face 32 -shell 1 -solid 1
CheckIsFeatureRemoved gap {v e f}

View File

@@ -13,18 +13,18 @@ compound feature1 feature2 feature3 gap
removefeatures res1 s feature1 feature2
checkshape res1
checkprops res1 -s 2387.88 -v 1060.71 -deps 1.e-7
checknbshapes res1 -vertex 68 -edge 102 -wire 36 -face 36 -shell 1 -solid 1
checknbshapes res1 -vertex 65 -edge 97 -wire 34 -face 34 -shell 1 -solid 1
CheckIsFeatureRemoved feature1 {v e f}
CheckIsFeatureRemoved feature2 {v e f}
removefeatures res2 s feature3
checkshape res2
checkprops res2 -s 2391.13 -v 1064.08 -deps 1.e-7
checknbshapes res2 -vertex 66 -edge 99 -wire 35 -face 35 -shell 1 -solid 1
checknbshapes res2 -vertex 63 -edge 94 -wire 33 -face 33 -shell 1 -solid 1
CheckIsFeatureRemoved feature3 {v e f}
removefeatures res3 s gap
checkshape res3
checkprops res3 -s 2392.93 -v 1065.38 -deps 1.e-7
checknbshapes res3 -vertex 60 -edge 90 -wire 32 -face 32 -shell 1 -solid 1
checknbshapes res3 -vertex 57 -edge 85 -wire 30 -face 30 -shell 1 -solid 1
CheckIsFeatureRemoved gap {v e f}

View File

@@ -10,5 +10,5 @@ compound s_11 s_13 s_12 spike
removefeatures res s spike
checkshape res
checkprops res -s 2323.49 -v 1037.57 -deps 1.e-7
checknbshapes res -vertex 64 -edge 96 -wire 34 -face 34 -shell 1 -solid 1
checknbshapes res -vertex 61 -edge 91 -wire 32 -face 32 -shell 1 -solid 1
CheckIsFeatureRemoved spike {v e f}

Some files were not shown because too many files have changed in this diff Show More