1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

Compare commits

...

33 Commits

Author SHA1 Message Date
jgv
85f78ac110 0031778: UnifySameDomain fails in Debug mode
Correct unification of circular edges: avoid trying to make an axis with null magnitude.
2020-10-06 18:18:23 +03:00
mkrylova
b601c8b883 0031688: Visualization - Wrong ISO lines for a face created from BSpline
Added a check to see if the ISO line intersects the bounding contour.
2020-09-30 13:51:49 +03:00
jgv
701db8a032 Add include line to hxx 2020-08-25 01:00:19 +03:00
jfa
14d4a8f2b6 Increment service pack version to 2 2020-07-31 18:39:11 +03:00
jgv
1d5cadffa7 0031617: Export STEP in nonmanifold mode corrupts the shape 2020-07-29 14:20:55 +03:00
emv
bbb7f3fa94 0031604: Wrong result of Boolean Operation Cut
BOPAlgo_WireSplitter::Path - continue building the next loop with the last edge not included into found loop.
2020-07-23 13:22:52 +03:00
jgv
fb343bc09d 0031485: Data Exchange - Export STEP in nonmanifold mode looses all faces except one
Small correction in STEPControl_ActorWrite::TransferCompound - take into account the case when a subshape has type TopAbs_FACE.
2020-07-23 13:18:58 +03:00
jgv
aba38db503 0031558: BRepOffsetAPI_MakeFilling algorithm makes turned inside out face
1. Modification in method BRepFill_Filling::Build - correction of building the wire.
2. Create new subgroup "filling" in the group "bugs".
2020-07-23 13:13:33 +03:00
azv
781c69588c 0031016: Projection of an ellipse is a B-spline in some cases
Improve projection of ellipse and circle on a plane in case of the same parametrization of the original curve and the projected one is not necessary. Now the projection is a canonical curve instead on B-spline.
2020-07-07 23:10:12 +03:00
jfa
12dbdf5483 0031565: Visualization - SIGFPE, Arithmetic exception if SelectMgr_TriangularFrustumSet::Build() is called with single point 2020-05-18 13:13:21 +03:00
mzernova
7904c7361f 0031440: Visualization - Impossible to make common behaviour for multi-selection in viewer
A special mode for the selecting by polygon is added to select only completely overlapping objects.

In order to track the sensitives that were included completely by defined polygon, the boundary points of the polygonal frustrum are stored in the variable myBoundaryPoints.

If an sensitive intersects with at least one of the frustrums from myFrustums, then checking whether this object intersects with borders using the isIntersectBoundary method; if not, then the sensitive were included completely by defined polygon.

Because the polygon can be concave, then to check the sensitive were included completely by defined polygon, it is not enough to check of all its points, it is necessary that the edges of the sensitive do not intersect polygonal frustrum. To do this, for polygonal selection, a call to the Overlaps method for a point was replaced by a call to a segment where necessary.

bugs/vis/bug31440: test case added
2020-04-30 16:33:31 +03:00
kgv
613213f3b7 0031425: Visualization - free Edge has selection sensitivity inconsistent to presentation
BRepTools::Triangulation() has been extended with a new parameter for checking Poly_Polygon3D presense within free Edges.
StdPrs_WFShape::Add() now performs auto-triangulation in the same way as StdPrs_ShadedShape::Add().
StdSelect_BRepSelectionTool::GetEdgeSensitive() now creates Select3D_SensitiveSegment instead of Select3D_SensitiveCurve for tessellated segment.
Select3D_SensitiveSegment default sensitivity factor has been changed to 3 pixels to match Select3D_SensitiveCurve.

Test case bug23625_1, added workaround for out-of-range crash in HLRBRep_PolyAlgo on re-triangulated shape.
2020-04-30 16:15:57 +03:00
jgv
e44cf1e4da 0031470: Modeling Algorithms - Regression: BOP common produces empty result (box and holed sphere)
Approx_ComputeCLine.gxx : new class field is added to manage hang checking.
ProjLib/ProjLib_ComputeApprox.cxx : unset hang checking for analytical surfaces and curves
2020-04-23 16:46:36 +03:00
jfa
a28d897290 Revert "0031470: Modeling Algorithms - Regression: BOP common produces empty result (box and holed sphere)"
This reverts commit b90477afe33ec585fec43fe5286bd2e2b93e21de.
2020-04-23 16:46:09 +03:00
jgv
e5f648be49 0031464: BRepOffsetAPI_MakeFilling algorithm increases tolerances of vertices in input edges
Modify history in BRepFill_Filling: now vertices are also stored in the map.
2020-04-23 15:39:31 +03:00
mpv
4c0aa1bc46 0031207: Regression in Boolean Operations: fuse gives wrong result
ForceInterfEE, ForceInterfEF - Use normalized vectors for angle computation. Increase the criteria angle.
2020-04-16 10:47:53 +03:00
emv
33d9a6fa21 0031462: Modeling Algorithms - BOP result depends on the arguments order
Eliminate numerical instability by ensuring that the tolerance of intersection entities is slightly grater than the actual distance to the shapes creating the entity.
2020-04-01 16:52:54 +03:00
jgv
b90477afe3 0031470: Modeling Algorithms - Regression: BOP common produces empty result (box and holed sphere)
Approx_ComputeCLine.gxx : number of possible cuttings is increased, tolerance in U parameter is reduced.
2020-03-31 15:50:47 +03:00
jgv
b3f078f474 0031441: UnifySameDomain corrupts the shape
Local function TransformPCurves is modified to process correctly same-domain elementary surfaces with different local coordinate systems.
2020-03-27 17:19:24 +03:00
ifv
1af716b9f3 0031415: Modeling Algorithms - Solid classifier works incorrectly on a cylinder
BRepClass3d_SClassifier.cxx : revert integration for CR29712

Test case added
2020-03-27 17:18:20 +03:00
ifv
87859c5534 0031460: Modeling Algorithms - Regression: Revolution not done.
BRepPrimAPI_MakeRevol.cxx: check of intersection of edge with rotation axis is improved.
Test case added
2020-03-27 17:16:57 +03:00
ifv
8c645a3f5d 0031404: Modeling Algorithms - BOP Fuse produces a self-interfering or a good shape depending on the order of arguments
Approx_ComputeCLine.gxx : number of possible cuttings is increased

tests/bugs/modalg_7/bug31404 : test case added
2020-03-27 17:15:43 +03:00
azv
bdeea0a897 0031407: [Regression to 7.3.0] Extrema does not process parallel circles correctly
Use correct ranges of circles when processing the concentric case. Repeat the range comparison 3 times shifting each time for a half-period to process the extrema between boundary points of arcs.
2020-03-06 14:57:11 +03:00
emv
08c8ef725c 0030386: Modeling Algorithms - Unable to perform Cut operation 2020-03-06 14:49:22 +03:00
jgv
8ce6d4990b 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.
2020-03-05 19:39:54 +03:00
ifv
4f9985be61 0031242: Scaling with different coefficients along axes produces invalid shape
GeomConvert_1.cxx:
Creation periodic BSpline surfaces from trimmed periodic surface if trim is boundaries of periodic domain is allowed

BRepTools_NurbsConvertModification.cxx:
Checking domain of 2dCurves if surfaces are periodic is added

Test case tests/bugs/mesh/bug30008_2 is modified according to current behavior

Test case tests/bugs/modalg_7/bug31242 is added
2020-03-05 17:40:29 +03:00
ifv
d2676fb8f3 0031294: Modeling Algorithms - Regression relatively 7.3.0. Crash in method BRepPrimAPI_MakePrism::Generated(...)
BRepSweep_NumLinearRegularSweep.cxx: raising exeption is removed

Test case is added

QABugs_20.cxx - test command is added
2020-01-14 15:43:59 +03:00
ifv
6b3be99225 0031031: Incorrect result is returned from BRepPrimAPI_MakePrism::Generated()
1. src\BRepSweep\BRepSweep_NumLinearRegularSweep.cxx

Fix bug by adding result in list of generated shapes, if initial shape is vertex, edge or face.

2. src\BRepLib\BRepLib.cxx

Add protection against treatment not geometric edge in BRepLib::UpdateInnerTolerances(...)

3. Add test case for bug and correct test for bug 30346 according to new behavior of algorithm
2020-01-14 15:42:38 +03:00
jgv
de7da66916 0030597: Result of BRepOffsetAPI_MakePipeShell doesn't match the given profiles
Modify the local function EdgeToBSpline of BRepFill_NSections to build a BSpline curve of general type for each curve of profile.
2019-12-26 15:48:36 +03:00
vsv
a130d492e0 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.
2019-12-26 13:48:10 +03:00
jgv
a2ac649fd1 0026071: BRepOffsetAPI_MakePipeShell produces rough result
1. Correct building history: the case of closed spine.
2. Rollback method GeomFill_CorrectedFrenet::InitInterval - correct processing singularities on spine.
3. Correct test cases.
2019-12-26 13:48:02 +03:00
jgv
f160ca4ef7 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-12-26 13:47:54 +03:00
emv
7e8a88210c 0029843: Modeling Algorithms - Boolean FUSE produces incorrect result
When splitting the shell/face with internal faces/edges use the 'internal' criteria of the face to choose the way to create loops.

Side effect changes:
- When performing Boolean operation - move the objects located far from Origin to the Origin to increase the accuracy of intersections.
2019-12-26 13:47:46 +03:00
185 changed files with 3358 additions and 962 deletions

View File

@ -1857,3 +1857,50 @@ The following API changes have been made:
@subsection upgrade_740_stdnamespace Standard_Stream.hxx no more has "using std::" statements
*Standard_Stream.hxx* header, commonly included by other OCCT header files, does no more add entities from *std namespace* related to streams (like *std::cout*, *std::istream* and others) into global namespace.
The application code relying on this matter should be updated to either specify std namespace explicitly (like std::cout) or add "using std::" statements locally.
<<<<<<< HEAD
=======
@section upgrade_occt750 Upgrade to OCCT 7.5.0
@subsection upgrade_750_srgb_color RGB color definition
OCCT 3D Viewer has been improved to properly perform lighting using in linear RGB color space and then convert result into non-linear gamma-shifted sRGB color space before displaying on display.
This change affects texture mapping, material definition and color definition.
Previously *Quantity_Color* definition was provided with unspecified RGB color space.
In practice, mixed color spaces have been actually used, with non-linear sRGB prevailing in general.
Since OCCT 7.5.0, *Quantity_Color* now specifies that components are defined in linear RGB color space.
This change affects following parts:
* Standard colors defined by *Quantity_NameOfColor* enumeration have been converted into linear RGB values within Quantity_Color construction.
* Application may use new enumeration value *Quantity_TOC_sRGB* for passing/fetching colors in sRGB color space,
which can be useful for interoperation with color picking widgets (returning 8-bit integer values within [0..255] range)
or for porting colors constants within old application code without manual conversion.
* *Graphic3d_MaterialAspect* color components are now expected in linear RGB color space,
and standard OCCT materials within *Graphic3d_NameOfMaterial* enumeration have been updated accordingly.
* Texture mapping now handles new *Graphic3d_TextureRoot::IsColorMap()* for interpreting content in linear RGB or sRGB color space.
It is responsibility of user specifying this flag correctly. The flag value is TRUE by default.
* Method *Image_PixMap::PixelColor()* has been extended with a new Boolean flag for performing linearization of non-linear sRGB.
This flag is FALSE by default; application should consider passing TRUE instead for further handling *Quantity_Color* properly as linear RGB values.
@subsection upgrade_750_aspectwindow Aspect_Window interface change
Unexpected const-ness of Aspect_Window::DoResize() method has been removed, so that application classes implementing this interface should be updated accordingly.
@subsection upgrade_750_rename Renaming of types
Enumeration BRepOffset_Type is renamed to ChFiDS_TypeOfConcavity.
@subsection upgrade_750_sensitiveEntity Select3D_SensitiveEntity interface change
The method Select3D_SensitiveEntity::NbSubElements() has been changed to be constant. Select3D_SensitiveEntity subclasses at application level should be updated accordingly.
@subsection upgrade_750_Booleans Changes in Boolean operations algorithm
* TreatCompound method has been moved from *BOPAlgo_Tools* to *BOPTools_AlgoTools*. Additionally, the map parameter became optional:
~~~~
void BOPTools_AlgoTools::TreatCompound (const TopoDS_Shape& theS,
TopTools_ListOfShape& theLS,
TopTools_MapOfShape* theMap = NULL);
~~~~

View File

@ -121,21 +121,21 @@ eval compound [explode mass w] mass
compound sample occ name material sheets scale mass text
compound snowflake lines text drawing
bounding snowflake -save x1 y1 z1 x2 y2 z2
# display in 3d view
vinit Driver1/Viewer1/View1 w=1024 h=768
vdisplay snowflake lines text
vrenderparams -msaa 8
vsetcolor snowflake 0 0 0
vsetcolor lines 0 0 0
vsetcolor text 0 0 0
vsetcolor snowflake BLACK
vsetcolor lines BLACK
vsetcolor text BLACK
vbackground -color WHITE
vtop
vfit
# add dimension:
# detect vertices extremal in X direction
bounding snowflake -save x1 y1 z1 x2 y2 z2
plane f1 x1 0 0 1 0 0
plane f2 x2 0 0 1 0 0
mkface f1 f1
@ -159,7 +159,3 @@ for {set i 1} {$i <= 2} {incr i} {
}
}
vdimension length -length -shapes $v1 $v2 -plane xoy -value 0.001 -dispunits mm -showunits -flyout 70 -label above -color black -text 5 3d sh
if { [regexp HAVE_GL2PS [dversion]] } {
puts "You can use command vexport to generate PDF: vexport your_file_path.pdf"
}

View File

@ -65,13 +65,15 @@ namespace
typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_IndexedMapOfOwner)>::Iterator AIS_MapIteratorOfMapOfObjectOwners;
//! Initialize default highlighting attributes.
static void initDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
static void initDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer,
const Quantity_Color& theColor)
{
theDrawer->SetMethod (Aspect_TOHM_COLOR);
theDrawer->SetDisplayMode (0);
theDrawer->SetColor (theColor);
theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
*theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
theDrawer->SetupOwnShadingAspect();
theDrawer->SetupOwnPointAspect();
theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
*theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
@ -82,6 +84,24 @@ namespace
*theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
*theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
theDrawer->SetDatumAspect (new Prs3d_DatumAspect());
theDrawer->ShadingAspect()->SetColor (theColor);
theDrawer->WireAspect()->SetColor (theColor);
theDrawer->LineAspect()->SetColor (theColor);
theDrawer->PlaneAspect()->ArrowAspect()->SetColor (theColor);
theDrawer->PlaneAspect()->IsoAspect()->SetColor (theColor);
theDrawer->PlaneAspect()->EdgesAspect()->SetColor (theColor);
theDrawer->FreeBoundaryAspect()->SetColor (theColor);
theDrawer->UnFreeBoundaryAspect()->SetColor (theColor);
theDrawer->PointAspect()->SetColor (theColor);
for (Standard_Integer aPartIter = 0; aPartIter < Prs3d_DP_None; ++aPartIter)
{
if (Handle(Prs3d_LineAspect) aLineAsp = theDrawer->DatumAspect()->LineAspect ((Prs3d_DatumParts )aPartIter))
{
aLineAsp->SetColor (theColor);
}
}
theDrawer->WireAspect()->SetWidth (2.0);
theDrawer->LineAspect()->SetWidth (2.0);
@ -130,30 +150,26 @@ myIsAutoActivateSelMode(Standard_True)
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_Dynamic];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle);
initDefaultHilightAttributes (aStyle, Quantity_NOC_CYAN1);
aStyle->SetZLayer(Graphic3d_ZLayerId_Top);
aStyle->SetColor (Quantity_NOC_CYAN1);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_LocalDynamic];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle);
initDefaultHilightAttributes (aStyle, Quantity_NOC_CYAN1);
aStyle->SetZLayer(Graphic3d_ZLayerId_Topmost);
aStyle->SetColor (Quantity_NOC_CYAN1);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_Selected];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle);
initDefaultHilightAttributes (aStyle, Quantity_NOC_GRAY80);
aStyle->SetZLayer(Graphic3d_ZLayerId_UNKNOWN);
aStyle->SetColor (Quantity_NOC_GRAY80);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_LocalSelected];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle);
initDefaultHilightAttributes (aStyle, Quantity_NOC_GRAY80);
aStyle->SetZLayer(Graphic3d_ZLayerId_UNKNOWN);
aStyle->SetColor (Quantity_NOC_GRAY80);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_SubIntensity];

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>
@ -59,6 +60,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
@ -70,6 +73,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");
@ -135,7 +139,6 @@ void AIS_Trihedron::SetSize(const Standard_Real aValue)
myDrawer->DatumAspect()->SetAxisLength(aValue, aValue, aValue);
SetToUpdate();
UpdatePresentations();
UpdateSelection();
}
@ -163,7 +166,6 @@ void AIS_Trihedron::UnsetSize()
else
{
SetToUpdate();
UpdatePresentations();
}
UpdateSelection();
}
@ -310,36 +312,37 @@ 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));
if (aPresentation->GetZLayer() != theStyle->ZLayer())
const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN ? theStyle->ZLayer() : myDrawer->ZLayer();
if (aPresentation->GetZLayer() != aLayer)
{
aPresentation->SetZLayer (theStyle->ZLayer());
aPresentation->SetZLayer (aLayer);
}
aPresentation->Highlight (theStyle);
thePM->AddToImmediateList (aPresentation);
}
@ -356,25 +359,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;
}
@ -382,27 +382,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());
}
}
}
@ -426,9 +422,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());
}
@ -553,11 +549,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);
}
}
@ -933,65 +926,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

@ -186,9 +186,6 @@ public:
public:
//! Disables auto highlighting to use HilightSelected() and HilightOwnerWithColor() overridden methods.
virtual Standard_Boolean IsAutoHilight() const Standard_OVERRIDE { return false; }
//! Method which clear all selected owners belonging
//! to this selectable object ( for fast presentation draw ).
Standard_EXPORT virtual void ClearSelected() Standard_OVERRIDE;
@ -248,13 +245,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;
@ -269,10 +259,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

@ -2192,7 +2192,6 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
aPolyIter.ChangeValue() = gp_Pnt2d (aNewPnt.x(), -aNewPnt.y());
}
theCtx->MainSelector()->AllowOverlapDetection (false);
if (myGL.Selection.IsXOR)
{
theCtx->ShiftSelect (aPolyline, theView, false);
@ -2201,6 +2200,7 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
{
theCtx->Select (aPolyline, theView, false);
}
theCtx->MainSelector()->AllowOverlapDetection (false);
}
}

View File

@ -54,6 +54,7 @@ const AppParCurves_Constraint LastC)
mylastC = LastC;
myMaxSegments = MAXSEGM;
myInvOrder = Standard_True;
myHangChecking = Standard_True;
alldone = Standard_False;
Perform(Line);
}
@ -82,6 +83,7 @@ const AppParCurves_Constraint LastC)
mylastC = LastC;
myMaxSegments = MAXSEGM;
myInvOrder = Standard_True;
myHangChecking = Standard_True;
}
//=======================================================================
@ -97,12 +99,20 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
Standard_Real thetol3d = Precision::Confusion(), thetol2d = Precision::Confusion();
UFirst = Line.FirstParameter();
ULast = Line.LastParameter();
Standard_Real TolU = Max((ULast - UFirst)*1.e-03, Precision::Confusion());
Standard_Real TolU = 0.;
if (myHangChecking)
{
TolU = Max((ULast - UFirst)*1.e-03, Precision::Confusion());
}
else
{
TolU = Max((ULast - UFirst)*1.e-05, Precision::PApproximation());
}
Standard_Real myfirstU = UFirst;
Standard_Real mylastU = ULast;
Standard_Integer aMaxSegments = 0;
Standard_Integer aMaxSegments1 = myMaxSegments - 1;
Standard_Integer aNbCut = 0, aNbImp = 0, aNbComp = 5;
Standard_Integer aNbCut = 0, aNbImp = 0, aNbComp = 10;
if (!mycut)
{
@ -176,12 +186,14 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
//cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl;
Standard_Boolean aStopCutting = Standard_False;
if (aNbCut >= aNbComp)
if (myHangChecking && aNbCut >= aNbComp)
{
if (aNbCut > aNbImp)
if (aNbCut > aNbImp + 1)
{
aStopCutting = Standard_True;
}
aNbCut = 0;
aNbImp = 0;
}
// is new decision better?
if (!Ok && (Abs(myfirstU - mylastU) <= TolU || aMaxSegments >= aMaxSegments1 || aStopCutting ))
@ -432,6 +444,15 @@ void Approx_ComputeCLine::SetInvOrder(const Standard_Boolean theInvOrder)
myInvOrder = theInvOrder;
}
//=======================================================================
//function : SetHangChecking
//purpose :
//=======================================================================
void Approx_ComputeCLine::SetHangChecking(const Standard_Boolean theHangChecking)
{
myHangChecking = theHangChecking;
}
//=======================================================================
//function : IsAllApproximated
//purpose : returns False if at a moment of the approximation,

View File

@ -70,6 +70,12 @@ public:
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! Set value of hang checking flag
//! if this flag = true, possible hang of algorithm is checked
//! and algorithm is forced to stop.
//! By default hang checking is used.
Standard_EXPORT void SetHangChecking(const Standard_Boolean theHangChecking);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@ -125,6 +131,7 @@ private:
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
Standard_Boolean myHangChecking;
};

View File

@ -70,6 +70,12 @@ public:
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! Set value of hang checking flag
//! if this flag = true, possible hang of algorithm is checked
//! and algorithm is forced to stop.
//! By default hang checking is used.
Standard_EXPORT void SetHangChecking(const Standard_Boolean theHangChecking);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@ -125,6 +131,7 @@ private:
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
Standard_Boolean myHangChecking;
};

View File

@ -305,30 +305,27 @@ void BOPAlgo_ArgumentAnalyzer::TestTypes()
return;
}
//
Standard_Integer aDim1, aDim2;
Standard_Boolean bBadTypes = Standard_False;
//
aDim1 = BOPTools_AlgoTools::Dimension(myShape1);
aDim2 = BOPTools_AlgoTools::Dimension(myShape2);
if (aDim1 < aDim2) {
if (myOperation == BOPAlgo_FUSE ||
myOperation == BOPAlgo_CUT21) {
bBadTypes = Standard_True;
if (myOperation != BOPAlgo_UNKNOWN &&
myOperation != BOPAlgo_COMMON)
{
Standard_Integer iDimMin[2], iDimMax[2];
BOPTools_AlgoTools::Dimensions(myShape1, iDimMin[0], iDimMax[0]);
BOPTools_AlgoTools::Dimensions(myShape2, iDimMin[1], iDimMax[1]);
Standard_Boolean bBadTypes =
((myOperation == BOPAlgo_FUSE) &&
(iDimMin[0] != iDimMax[0] || iDimMin[1] != iDimMax[1] || iDimMin[0] != iDimMin[1])) ||
((myOperation == BOPAlgo_CUT) && (iDimMax[0] > iDimMin[1])) ||
((myOperation == BOPAlgo_CUT21) && (iDimMin[0] < iDimMax[1]));
if (bBadTypes) {
BOPAlgo_CheckResult aResult;
aResult.SetShape1(myShape1);
aResult.SetShape2(myShape2);
aResult.SetCheckStatus(BOPAlgo_BadType);
myResult.Append(aResult);
}
}
else if (aDim1 > aDim2) {
if (myOperation == BOPAlgo_FUSE ||
myOperation == BOPAlgo_CUT) {
bBadTypes = Standard_True;
}
}
if (bBadTypes) {
BOPAlgo_CheckResult aResult;
aResult.SetShape1(myShape1);
aResult.SetShape2(myShape2);
aResult.SetCheckStatus(BOPAlgo_BadType);
myResult.Append(aResult);
}
}
}
//=======================================================================

View File

@ -122,7 +122,7 @@ BOPAlgo_Operation BOPAlgo_BOP::Operation()const
//=======================================================================
void BOPAlgo_BOP::CheckData()
{
Standard_Integer i, j, iDim, aNbArgs, aNbTools;
Standard_Integer i, j, aNbArgs, aNbTools;
Standard_Boolean bFuse;
TopTools_ListIteratorOfListOfShape aItLS;
//
@ -164,7 +164,8 @@ void BOPAlgo_BOP::CheckData()
// or equal to the MAXIMAL dimension of the TOOLS;
// 4. COMMON: The arguments and tools could have any dimensions.
//
Standard_Integer iDimMin[2] = { 0, 0 }, iDimMax[2] = { 0, 0 };
Standard_Integer iDimMin[2] = { 3, 3 },
iDimMax[2] = { 0, 0 };
Standard_Boolean bHasValid[2] = {Standard_False, Standard_False};
//
for (i=0; i<2; ++i) {
@ -173,38 +174,27 @@ void BOPAlgo_BOP::CheckData()
for (j=0; aItLS.More(); aItLS.Next(), ++j) {
const TopoDS_Shape& aS=aItLS.Value();
Standard_Boolean bIsEmpty = BOPTools_AlgoTools3D::IsEmptyShape(aS);
if (bIsEmpty) {
if (bIsEmpty)
{
AddWarning(new BOPAlgo_AlertEmptyShape (aS));
continue;
}
//
iDim = BOPTools_AlgoTools::Dimension(aS);
if (iDim < 0) {
Standard_Integer iDMin, iDMax;
BOPTools_AlgoTools::Dimensions(aS, iDMin, iDMax);
if (iDMin < iDimMin[i])
iDimMin[i] = iDMin;
if (iDMax > iDimMax[i])
iDimMax[i] = iDMax;
if (bFuse && (iDimMin[i] != iDimMax[i]))
{
// non-homogeneous argument
AddError (new BOPAlgo_AlertBOPNotAllowed);
return;
}
//
bHasValid[i] = Standard_True;
//
if (!j) {
iDimMin[i] = iDim;
iDimMax[i] = iDim;
continue;
}
//
if (iDim < iDimMin[i]) {
iDimMin[i] = iDim;
}
else if (iDim > iDimMax[i]) {
iDimMax[i] = iDim;
}
//
if (bFuse && (iDimMin[i] != iDimMax[i])) {
// non-homogeneous argument
AddError (new BOPAlgo_AlertBOPNotAllowed);
return;
}
}
}
//
@ -222,7 +212,7 @@ void BOPAlgo_BOP::CheckData()
if (bHasValid[0] || bHasValid[1])
{
// In case of all empty shapes in one of the groups
// this group aquires the dimension of other group
// this group acquires the dimension of other group
myDims[0] = bHasValid[0] ? iDimMin[0] : iDimMin[1];
myDims[1] = bHasValid[1] ? iDimMin[1] : iDimMin[0];
}
@ -583,12 +573,17 @@ void BOPAlgo_BOP::BuildRC()
aItLS.Initialize(aLS);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aS = aItLS.Value();
iDim = BOPTools_AlgoTools::Dimension(aS);
if (iDim < 0) {
continue;
TopTools_ListOfShape aList;
BOPTools_AlgoTools::TreatCompound (aS, aList);
for (TopTools_ListOfShape::Iterator itList (aList); itList.More(); itList.Next())
{
const TopoDS_Shape& aSS = itList.Value();
iDim = BOPTools_AlgoTools::Dimension (aSS);
if (iDim < 0)
continue;
aType = TypeToExplore (iDim);
TopExp::MapShapes (aSS, aType, aMS);
}
aType = TypeToExplore(iDim);
TopExp::MapShapes(aS, aType, aMS);
}
}
//
@ -930,7 +925,7 @@ void BOPAlgo_BOP::BuildShape()
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aS = aItLS.Value();
BOPAlgo_Tools::TreatCompound(aS, aMInpFence, aLSNonCont);
BOPTools_AlgoTools::TreatCompound(aS, aLSNonCont, &aMInpFence);
}
}

View File

@ -441,7 +441,7 @@ void BOPAlgo_Builder::BuildBOP(const TopTools_ListOfShape& theObjects,
{
TopTools_ListOfShape aLS;
TopTools_MapOfShape aMFence;
BOPAlgo_Tools::TreatCompound(aS, aMFence, aLS);
BOPTools_AlgoTools::TreatCompound(aS, aLS, &aMFence);
TopTools_ListOfShape::Iterator it(aLS);
for (; it.More(); it.Next())

View File

@ -550,7 +550,7 @@ void BOPAlgo_Builder::FillInternalShapes()
aIt.Initialize(aArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS=aIt.Value();
BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC);
BOPTools_AlgoTools::TreatCompound(aS, aLSC, &aMFence);
}
aIt.Initialize(aLSC);
for (; aIt.More(); aIt.Next()) {

View File

@ -141,44 +141,50 @@ void BOPAlgo_CellsBuilder::IndexParts()
TopTools_ListIteratorOfListOfShape aIt(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
//
Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
aMDims.Add(iDim);
TopAbs_ShapeEnum aType = TypeToExplore(iDim);
//
TopExp_Explorer aExp(aS, aType);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aST = aExp.Current();
const TopTools_ListOfShape* pLSIm = myImages.Seek(aST);
if (!pLSIm) {
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aST);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aST, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aST)) {
aBB.Add(anAllParts, aST);
TopTools_ListOfShape aLSubS;
BOPTools_AlgoTools::TreatCompound (aS, aLSubS);
for (TopTools_ListOfShape::Iterator itSub (aLSubS); itSub.More(); itSub.Next())
{
const TopoDS_Shape& aSS = itSub.Value();
Standard_Integer iDim = BOPTools_AlgoTools::Dimension (aSS);
aMDims.Add(iDim);
TopAbs_ShapeEnum aType = TypeToExplore (iDim);
TopExp_Explorer aExp (aSS, aType);
for (; aExp.More(); aExp.Next())
{
const TopoDS_Shape& aST = aExp.Current();
const TopTools_ListOfShape* pLSIm = myImages.Seek(aST);
if (!pLSIm) {
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aST);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aST, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aST)) {
aBB.Add(anAllParts, aST);
}
//
continue;
}
//
continue;
}
//
TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
for (; aItIm.More(); aItIm.Next()) {
const TopoDS_Shape& aSTIm = aItIm.Value();
//
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aSTIm, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aSTIm)) {
aBB.Add(anAllParts, aSTIm);
}
} // for (; aItIm.More(); aItIm.Next()) {
} // for (; aExp.More(); aExp.Next()) {
TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
for (; aItIm.More(); aItIm.Next()) {
const TopoDS_Shape& aSTIm = aItIm.Value();
//
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aSTIm, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aSTIm)) {
aBB.Add(anAllParts, aSTIm);
}
} // for (; aItIm.More(); aItIm.Next()) {
} // for (; aExp.More(); aExp.Next()) {
} // for (; itSub.More(); itSub.Next())
} // for (; aIt.More(); aIt.Next()) {
//
myAllParts = anAllParts;

View File

@ -75,7 +75,7 @@ void BOPAlgo_MakeConnected::CheckData()
TopTools_ListIteratorOfListOfShape itLA(myArguments);
for (; itLA.More(); itLA.Next())
BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLA);
BOPTools_AlgoTools::TreatCompound(itLA.Value(), aLA, &aMFence);
if (aLA.IsEmpty())
{
@ -197,7 +197,7 @@ void BOPAlgo_MakeConnected::AssociateMaterials()
// Extract all non-compound shapes from the result
TopTools_ListOfShape aLShapes;
TopTools_MapOfShape aMFence;
BOPAlgo_Tools::TreatCompound(myShape, aMFence, aLShapes);
BOPTools_AlgoTools::TreatCompound(myShape, aLShapes, &aMFence);
if (aLShapes.IsEmpty())
return;

View File

@ -342,7 +342,7 @@ void BOPAlgo_MakerVolume::FillInternalShapes(const TopTools_ListOfShape& theLSR)
TopTools_ListOfShape::Iterator itLA(myDS->Arguments());
for (; itLA.More(); itLA.Next())
BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLSC);
BOPTools_AlgoTools::TreatCompound(itLA.Value(), aLSC, &aMFence);
// Get only edges and vertices from arguments
TopTools_ListOfShape aLVE;

View File

@ -225,6 +225,14 @@ void BOPAlgo_PaveFiller::IntersectVE
const Handle(BOPDS_PaveBlock)& aPB = theVEPairs.FindKey(i);
Standard_Integer nE = aPB->OriginalEdge();
//
TColStd_MapOfInteger aMVPB;
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE);
for (BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); itPB.More(); itPB.Next())
{
aMVPB.Add (itPB.Value()->Pave1().Index());
aMVPB.Add (itPB.Value()->Pave2().Index());
}
const TColStd_ListOfInteger& aLV = theVEPairs(i);
TColStd_ListIteratorOfListOfInteger aItLV(aLV);
for (; aItLV.More(); aItLV.Next()) {
@ -233,6 +241,9 @@ void BOPAlgo_PaveFiller::IntersectVE
Standard_Integer nVSD = nV;
myDS->HasShapeSD(nV, nVSD);
//
if (aMVPB.Contains (nVSD))
continue;
BOPDS_Pair aPair(nVSD, nE);
TColStd_ListOfInteger* pLI = aDMVSD.ChangeSeek(aPair);
if (pLI) {
@ -287,7 +298,21 @@ void BOPAlgo_PaveFiller::IntersectVE
Standard_Integer nVx = UpdateVertex(nV, aTolVNew);
// 2. Create new pave and add it as extra pave to pave block
// for further splitting of the edge
const Handle(BOPDS_PaveBlock)& aPB = aVESolver.PaveBlock();
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE);
// Find the appropriate one
Handle(BOPDS_PaveBlock) aPB;
BOPDS_ListOfPaveBlock::Iterator itPB (aLPB);
for (; itPB.More(); itPB.Next())
{
aPB = itPB.Value();
Standard_Real aT1, aT2;
aPB->Range (aT1, aT2);
if (aT > aT1 && aT < aT2)
break;
}
if (!itPB.More())
continue;
BOPDS_Pave aPave;
aPave.SetIndex(nVx);
aPave.SetParameter(aT);

View File

@ -89,28 +89,63 @@ class BOPAlgo_EdgeEdge :
Handle(BOPDS_PaveBlock)& PaveBlock2() {
return myPB2;
}
//
//
void SetBoxes (const Bnd_Box& theBox1,
const Bnd_Box& theBox2)
{
myBox1 = theBox1;
myBox2 = theBox2;
}
//
void SetFuzzyValue(const Standard_Real theFuzz) {
IntTools_EdgeEdge::SetFuzzyValue(theFuzz);
}
//
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
TopoDS_Edge anE1 = myEdge1, anE2 = myEdge2;
Standard_Boolean hasTrsf = false;
try
{
OCC_CATCH_SIGNALS
gp_Trsf aTrsf;
if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
{
// Shapes are located far from origin, move the shapes to the origin,
// to increase the accuracy of intersection.
TopLoc_Location aLoc (aTrsf);
myEdge1.Move (aLoc);
myEdge2.Move (aLoc);
hasTrsf = Standard_True;
}
IntTools_EdgeEdge::Perform();
}
catch (Standard_Failure const&)
{
AddError(new BOPAlgo_AlertIntersectionFailed);
}
myEdge1 = anE1;
myEdge2 = anE2;
if (hasTrsf)
{
for (Standard_Integer i = 1; i <= myCommonParts.Length(); ++i)
{
IntTools_CommonPrt& aCPart = myCommonParts (i);
aCPart.SetEdge1 (myEdge1);
aCPart.SetEdge2 (myEdge2);
}
}
}
//
protected:
Handle(BOPDS_PaveBlock) myPB1;
Handle(BOPDS_PaveBlock) myPB2;
Bnd_Box myBox1;
Bnd_Box myBox2;
};
//
//=======================================================================
@ -216,6 +251,7 @@ void BOPAlgo_PaveFiller::PerformEE()
//
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
anEdgeEdge.SetBoxes (aBB1, aBB2);
anEdgeEdge.SetFuzzyValue(myFuzzyValue);
anEdgeEdge.SetProgressIndicator(myProgressIndicator);
}//for (; aIt2.More(); aIt2.Next()) {
@ -924,6 +960,8 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
if (!aNbPB)
return;
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
// Prepare pave blocks with the same vertices for intersection.
BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
@ -940,10 +978,12 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
// Use the max tolerance of vertices as Fuzzy value for intersection
// of edges
Standard_Real aTolAdd = 2 * Max(BRep_Tool::Tolerance(aV1),
BRep_Tool::Tolerance(aV2));
// Use the max tolerance of vertices as Fuzzy value for intersection of edges.
// In the Self-Interference check mode we are interested in real
// intersections only, so use only the real tolerance of edges,
// no need to use the extended tolerance.
Standard_Real aTolAdd = (bSICheckMode ? myFuzzyValue :
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
// All possible pairs combined from the list <aLPB> should be checked
BOPDS_ListIteratorOfListOfPaveBlock aItLPB1(aLPB);
@ -962,6 +1002,7 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
aBAC1.D1((aT11 + aT12) * 0.5, aPm, aVTgt1);
if (aVTgt1.SquareMagnitude() < gp::Resolution())
continue;
aVTgt1.Normalize();
BOPDS_ListIteratorOfListOfPaveBlock aItLPB2 = aItLPB1;
for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next())
@ -994,25 +1035,30 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
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
// If the angle is more than 25 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;
if (aBAC1.GetType() != GeomAbs_Line ||
aBAC2.GetType() != GeomAbs_Line)
{
GeomAPI_ProjectPointOnCurve& aProjPC = myContext->ProjPC(aE2);
aProjPC.Perform(aPm);
if (!aProjPC.NbPoints())
continue;
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.Normalized());
if (Abs(aCos) < 0.9063)
bUseAddTol = Standard_False;
}
}
// Add pair for intersection
@ -1022,6 +1068,7 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
anEdgeEdge.SetPaveBlock2(aPB2);
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
anEdgeEdge.SetBoxes (myDS->ShapeInfo(nE1).Box(), myDS->ShapeInfo (nE2).Box());
if (bUseAddTol)
anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
else

View File

@ -105,18 +105,50 @@ class BOPAlgo_EdgeFace :
IntTools_EdgeFace::SetFuzzyValue(theFuzz);
}
//
void SetBoxes (const Bnd_Box& theBox1,
const Bnd_Box& theBox2)
{
myBox1 = theBox1;
myBox2 = theBox2;
}
//
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
TopoDS_Face aFace = myFace;
TopoDS_Edge anEdge = myEdge;
Standard_Boolean hasTrsf = false;
try
{
OCC_CATCH_SIGNALS
gp_Trsf aTrsf;
if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
{
// Shapes are located far from origin, move the shapes to the origin,
// to increase the accuracy of intersection.
TopLoc_Location aLoc (aTrsf);
myEdge.Move (aLoc);
myFace.Move (aLoc);
hasTrsf = Standard_True;
}
IntTools_EdgeFace::Perform();
}
catch (Standard_Failure const&)
{
AddError(new BOPAlgo_AlertIntersectionFailed);
}
myFace = aFace;
myEdge = anEdge;
if (hasTrsf)
{
for (Standard_Integer i = 1; i <= mySeqOfCommonPrts.Length(); ++i)
{
IntTools_CommonPrt& aCPart = mySeqOfCommonPrts (i);
aCPart.SetEdge1 (myEdge);
}
}
}
//
protected:
@ -124,6 +156,8 @@ class BOPAlgo_EdgeFace :
Standard_Integer myIF;
IntTools_Range myNewSR;
Handle(BOPDS_PaveBlock) myPB;
Bnd_Box myBox1;
Bnd_Box myBox2;
};
//
//=======================================================================
@ -231,6 +265,7 @@ void BOPAlgo_PaveFiller::PerformEF()
//
aEdgeFace.SetEdge (aE);
aEdgeFace.SetFace (aF);
aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
aEdgeFace.SetFuzzyValue(myFuzzyValue);
aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
//
@ -756,6 +791,8 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
// Shake the tree
aBBTree.Build();
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
// Find pairs of Face/PaveBlock containing the same vertices
// and prepare those pairs for intersection.
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
@ -810,6 +847,7 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
// Projection tool
GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
BRepAdaptor_Surface& aSurfAdaptor = myContext->SurfaceAdaptor (aF);
// Iterate on pave blocks and combine pairs containing
// the same vertices
@ -849,7 +887,7 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
// 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
// of the face is not in the range of 65 - 115 degrees, do not use the additional
// tolerance, as it may lead to undesired unification of edge with the face.
Standard_Boolean bUseAddTol = Standard_True;
@ -874,8 +912,12 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
// 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));
// In the Self-Interference check mode we are interested in real
// intersections only, so use only the real tolerance of edges,
// no need to use the extended tolerance.
Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
continue;
@ -885,15 +927,19 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V)))
continue;
gp_Pnt aPOnS = aProjPS.NearestPoint();
gp_Vec aVFNorm(aPOnS, aPOnE);
if (aVFNorm.SquareMagnitude() > gp::Resolution())
if (aSurfAdaptor.GetType() != GeomAbs_Plane ||
aBAC.GetType() != GeomAbs_Line)
{
// 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;
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 25 degrees.
Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized());
if (Abs(aCos) > 0.4226)
bUseAddTol = Standard_False;
}
}
// Compute an addition to Fuzzy value
@ -940,6 +986,7 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
aEdgeFace.SetPaveBlock(aPB);
aEdgeFace.SetEdge(aE);
aEdgeFace.SetFace(aF);
aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));

View File

@ -122,6 +122,12 @@ class BOPAlgo_FaceFace :
myF2=aF2;
}
//
void SetBoxes(const Bnd_Box& theBox1,
const Bnd_Box& theBox2) {
myBox1 = theBox1;
myBox2 = theBox2;
}
//
const TopoDS_Face& Face1()const {
return myF1;
}
@ -142,13 +148,37 @@ class BOPAlgo_FaceFace :
IntTools_FaceFace::SetFuzzyValue(theFuzz);
}
//
const gp_Trsf& Trsf() const { return myTrsf; }
//
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
try
{
OCC_CATCH_SIGNALS
IntTools_FaceFace::Perform(myF1, myF2);
gp_Trsf aTrsf;
TopoDS_Face aF1 = myF1, aF2 = myF2;
if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
{
// Shapes are located far from origin, move the shapes to the origin,
// to increase the accuracy of intersection.
TopLoc_Location aLoc (aTrsf);
aF1.Move (aLoc);
aF2.Move (aLoc);
// The starting point is initialized only with the UV parameters
// on the faces - 3D point is not set (see GetEFPnts method),
// so no need to transform anything.
//for (IntSurf_ListOfPntOn2S::Iterator it (myListOfPnts); it.More(); it.Next())
//{
// IntSurf_PntOn2S& aP2S = it.ChangeValue();
// aP2S.SetValue (aP2S.Value().Transformed (aTrsf));
//}
myTrsf = aTrsf.Inverted();
}
IntTools_FaceFace::Perform (aF1, aF2);
}
catch (Standard_Failure const&)
{
@ -156,12 +186,39 @@ class BOPAlgo_FaceFace :
}
}
//
void ApplyTrsf()
{
if (IsDone())
{
// Update curves
for (Standard_Integer i = 1; i <= mySeqOfCurve.Length(); ++i)
{
IntTools_Curve& aIC = mySeqOfCurve (i);
aIC.Curve()->Transform (myTrsf);
}
// Update points
for (Standard_Integer i = 1; i <= myPnts.Length(); ++i)
{
IntTools_PntOn2Faces& aP2F = myPnts (i);
IntTools_PntOnFace aPOnF1 = aP2F.P1(), aPOnF2 = aP2F.P2();
aPOnF1.SetPnt (aPOnF1.Pnt().Transformed (myTrsf));
aPOnF2.SetPnt (aPOnF2.Pnt().Transformed (myTrsf));
aP2F.SetP1 (aPOnF1);
aP2F.SetP2 (aPOnF2);
}
}
}
//
protected:
Standard_Integer myIF1;
Standard_Integer myIF2;
Standard_Real myTolFF;
TopoDS_Face myF1;
TopoDS_Face myF2;
Bnd_Box myBox1;
Bnd_Box myBox2;
gp_Trsf myTrsf;
};
//
//=======================================================================
@ -235,6 +292,7 @@ void BOPAlgo_PaveFiller::PerformFF()
//
aFaceFace.SetIndices(nF1, nF2);
aFaceFace.SetFaces(aF1, aF2);
aFaceFace.SetBoxes (myDS->ShapeInfo (nF1).Box(), myDS->ShapeInfo (nF2).Box());
// compute minimal tolerance for the curves
Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2);
aFaceFace.SetTolFF(aTolFF);
@ -282,6 +340,8 @@ void BOPAlgo_PaveFiller::PerformFF()
//
aFaceFace.PrepareLines3D(bSplitCurve);
//
aFaceFace.ApplyTrsf();
//
const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines();
const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points();
//
@ -1711,12 +1771,16 @@ void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
getBoundPaves(myDS, aNC, aBndNV);
//
Standard_Real aTolVnew = Precision::Confusion();
Standard_Boolean isClosed = aP[1].IsEqual (aP[0], aTolVnew);
if (isClosed && (aBndNV[0] > 0 || aBndNV[1] > 0))
return;
for (Standard_Integer j = 0; j<2; ++j)
{
if (aBndNV[j] < 0)
{
// no vertex on this end
if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
if (j && isClosed) {
//if curve is closed, process only one bound
continue;
}
@ -2350,7 +2414,7 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve
Standard_Integer nVUsed;
Standard_Real aPTol, aDTol;
//
aDTol = 1.e-12;
aDTol = BOPTools_AlgoTools::DTolerance();
//
GeomAdaptor_Curve aGAC(aIC.Curve());
aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
@ -2395,7 +2459,8 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve
aTolV = BRep_Tool::Tolerance(aV);
gp_Pnt aP2 = BRep_Tool::Pnt(aV);
Standard_Real aDist = aP1.Distance(aP2);
if (aDist > aTolV) {
if (aTolV < aDist + aDTol)
{
BRep_Builder().UpdateVertex(aV, aDist + aDTol);
//
if (!aMVTol.IsBound(nV)) {
@ -2767,7 +2832,7 @@ void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
if (aDistVP > aTolV)
{
Standard_Integer nVn = UpdateVertex(nV, aDistVP);
Standard_Integer nVn = UpdateVertex(nV, aDistVP + BOPTools_AlgoTools::DTolerance());
if (nVn != nV)
{
aPave.SetIndex(nVn);

View File

@ -784,7 +784,7 @@ void UpdateVertices(const TopoDS_Edge& aE,
aD2=aP3D.SquareDistance(aP3Dx);
if (aD2>aTolV2) {
aD=sqrt(aD2);
aBB.UpdateVertex(aV[j], aD);
aBB.UpdateVertex(aV[j], aD + BOPTools_AlgoTools::DTolerance());
}
}
}

View File

@ -181,7 +181,7 @@ void BOPAlgo_RemoveFeatures::CheckData()
TopTools_ListOfShape aShapes;
TopTools_MapOfShape aMFence;
// Extract all shapes from the compound
BOPAlgo_Tools::TreatCompound(myInputShape, aMFence, aShapes);
BOPTools_AlgoTools::TreatCompound(myInputShape, aShapes, &aMFence);
if (aShapes.IsEmpty())
{
// Add error of empty input shape

View File

@ -215,11 +215,15 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
//
// use only connected faces
TopTools_ListOfShape aLFConnected;
// Boundary faces
TopTools_MapOfShape aBoundaryFaces;
aItF.Initialize (myShapes);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Shape& aF = aItF.Value();
if (aMFaces.Contains(aF)) {
aLFConnected.Append(aF);
if (!aBoundaryFaces.Add (aF))
aBoundaryFaces.Remove (aF);
}
}
//
@ -254,6 +258,7 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
aItS.Initialize(aShell);
for (; aItS.More(); aItS.Next()) {
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
Standard_Boolean isBoundary = aBoundaryFaces.Contains (aF);
//
// loop on edges of aF; find a good neighbor face of aF by aE
aExp.Init(aF, TopAbs_EDGE);
@ -289,6 +294,8 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
// take only not-processed faces as a candidates
BOPTools_ListOfCoupleOfShape aLCSOff;
//
Standard_Integer aNbWaysInside = 0;
TopoDS_Face aSelF;
TopTools_ListIteratorOfListOfShape aItLF(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFL = (*(TopoDS_Face*)(&aItLF.Value()));
@ -301,6 +308,11 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
continue;
}
//
if (isBoundary && !aBoundaryFaces.Contains (aFL))
{
++aNbWaysInside;
aSelF = aFL;
}
aCSOff.SetShape1(aEL);
aCSOff.SetShape2(aFL);
aLCSOff.Append(aCSOff);
@ -313,12 +325,14 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
//
// among all the adjacent faces chose one with the minimal
// angle to the current one
TopoDS_Face aSelF;
if (aNbOff == 1) {
aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
}
else if (aNbOff > 1) {
BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext);
if (!isBoundary || aNbWaysInside != 1)
{
if (aNbOff == 1) {
aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
}
else if (aNbOff > 1) {
BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext);
}
}
//
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {

View File

@ -1103,29 +1103,6 @@ void BOPAlgo_Tools::IntersectVertices(const TopTools_IndexedDataMapOfShapeReal&
}
}
//=======================================================================
//function : TreatCompound
//purpose :
//=======================================================================
void BOPAlgo_Tools::TreatCompound(const TopoDS_Shape& theS,
TopTools_MapOfShape& aMFence,
TopTools_ListOfShape& theLS)
{
TopAbs_ShapeEnum aType = theS.ShapeType();
if (aType != TopAbs_COMPOUND)
{
if (aMFence.Add(theS))
theLS.Append(theS);
return;
}
TopoDS_Iterator aIt(theS);
for (; aIt.More(); aIt.Next())
{
const TopoDS_Shape& aS = aIt.Value();
TreatCompound(aS, aMFence, theLS);
}
}
//=======================================================================
// Classification of the faces relatively solids
//=======================================================================
@ -1756,3 +1733,30 @@ void BOPAlgo_Tools::FillInternals(const TopTools_ListOfShape& theSolids,
}
}
}
//=======================================================================
//function : TrsfToPoint
//purpose :
//=======================================================================
Standard_Boolean BOPAlgo_Tools::TrsfToPoint (const Bnd_Box& theBox1,
const Bnd_Box& theBox2,
gp_Trsf& theTrsf,
const gp_Pnt& thePoint,
const Standard_Real theCriteria)
{
// Unify two boxes
Bnd_Box aBox = theBox1;
aBox.Add (theBox2);
gp_XYZ aBCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) / 2.;
Standard_Real aPBDist = (thePoint.XYZ() - aBCenter).Modulus();
if (aPBDist < theCriteria)
return Standard_False;
Standard_Real aBSize = Sqrt (aBox.SquareExtent());
if ((aBSize / aPBDist) > (1. / theCriteria))
return Standard_False;
theTrsf.SetTranslation (gp_Vec (aBox.CornerMin(), thePoint));
return Standard_True;
}

View File

@ -165,13 +165,6 @@ public:
const Standard_Real theFuzzyValue,
TopTools_ListOfListOfShape& theChains);
//! Collect in the output list recursively all non-compound subshapes of the first level
//! of the given shape theS. If a shape presents in the map theMFence it is skipped.
//! All shapes put in the output are also added into theMFence.
Standard_EXPORT static void TreatCompound(const TopoDS_Shape& theS,
TopTools_MapOfShape& theMFence,
TopTools_ListOfShape& theLS);
//! Classifies the faces <theFaces> relatively solids <theSolids>.
//! The IN faces for solids are stored into output data map <theInParts>.
//!
@ -205,6 +198,20 @@ public:
const TopTools_DataMapOfShapeListOfShape& theImages,
const Handle(IntTools_Context)& theContext);
//! Computes the transformation needed to move the objects
//! to the given point to increase the quality of computations.
//! Returns true if the objects are located far from the given point
//! (relatively given criteria), false otherwise.
//! @param theBox1 the AABB of the first object
//! @param theBox2 the AABB of the second object
//! @param theTrsf the computed transformation
//! @param thePoint the Point to compute transformation to
//! @param theCriteria the Criteria to check whether thranformation is required
Standard_EXPORT static Standard_Boolean TrsfToPoint (const Bnd_Box& theBox1,
const Bnd_Box& theBox2,
gp_Trsf& theTrsf,
const gp_Pnt& thePoint = gp_Pnt (0.0, 0.0, 0.0),
const Standard_Real theCriteria = 1.e+5);
};
#endif // _BOPAlgo_Tools_HeaderFile

View File

@ -27,7 +27,9 @@ class BOPAlgo_EdgeInfo {
BOPAlgo_EdgeInfo() :
myPassed(Standard_False),
myInFlag(Standard_False),
myAngle (-1.) {
myIsInside (Standard_False),
myAngle (-1.)
{
};
//
void SetEdge(const TopoDS_Edge& theE) {
@ -62,10 +64,19 @@ class BOPAlgo_EdgeInfo {
return myAngle;
};
//
Standard_Boolean IsInside() const {
return myIsInside;
};
//
void SetIsInside (const Standard_Boolean theIsInside) {
myIsInside = theIsInside;
};
//
protected:
TopoDS_Edge myEdge;
Standard_Boolean myPassed;
Standard_Boolean myInFlag;
Standard_Boolean myIsInside;
Standard_Real myAngle;
};

View File

@ -94,6 +94,7 @@ static
static
void Path (const GeomAdaptor_Surface& aGAS,
const TopoDS_Face& myFace,
const MyDataMapOfShapeBoolean& aVertMap,
const TopoDS_Vertex& aVa,
const TopoDS_Edge& aEOuta,
BOPAlgo_EdgeInfo& anEdgeInfo,
@ -101,8 +102,7 @@ static
TopTools_SequenceOfShape& aVertVa,
TColgp_SequenceOfPnt2d& aCoordVa,
BOPTools_ConnexityBlock& aCB,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
MyDataMapOfShapeBoolean aVertMap);
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap);
static
Standard_Real Angle (const gp_Dir2d& aDir2D);
@ -122,7 +122,6 @@ static
static
void RefineAngles(const TopoDS_Face& myFace,
const TopTools_ListOfShape&,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo&,
const Handle(IntTools_Context)&);
@ -130,7 +129,6 @@ static
static
void RefineAngles(const TopoDS_Vertex& ,
const TopoDS_Face& ,
const TopTools_MapOfShape& ,
BOPAlgo_ListOfEdgeInfo&,
const Handle(IntTools_Context)&);
@ -166,6 +164,8 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
MyDataMapOfShapeBoolean aVertMap;
//
const TopTools_ListOfShape& myEdges=aCB.Shapes();
TopTools_MapOfShape aMS;
//
// 1.Filling mySmartMap
aIt.Initialize(myEdges);
@ -177,6 +177,10 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
//
bIsClosed = BRep_Tool::Degenerated(aE) ||
BRep_Tool::IsClosed(aE, myFace);
if (!aMS.Add (aE) && !bIsClosed)
aMS.Remove (aE);
//
aItS.Initialize(aE);
for(i = 0; aItS.More(); aItS.Next(), ++i) {
@ -218,7 +222,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
for (i=1; i<=aNb; i++) {
aCntIn=0;
aCntOut=0;
const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
const BOPAlgo_ListOfEdgeInfo& aLEInfo = mySmartMap(i);
BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
for (; anIt.More(); anIt.Next()) {
const BOPAlgo_EdgeInfo& aEI=anIt.Value();
@ -304,6 +308,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
for (; aItLEI.More(); aItLEI.Next()) {
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
const TopoDS_Edge& aE=aEI.Edge();
aEI.SetIsInside (!aMS.Contains (aE));
//
aVV = aV;
bIsIN = aEI.IsIn();
@ -317,7 +322,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
//Theme: The treatment p-curves convergent in node.
//The refining the angles of p-curves taking into account
//bounding curves if exist.
RefineAngles(myFace, myEdges, mySmartMap, theContext);
RefineAngles(myFace, mySmartMap, theContext);
//
// 4. Do
//
@ -341,8 +346,8 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
aVertVa.Clear();
aCoordVa.Clear();
//
Path(aGAS, myFace, aVa, aEOuta, aEI, aLS,
aVertVa, aCoordVa, aCB, mySmartMap, aVertMap);
Path(aGAS, myFace, aVertMap, aVa, aEOuta, aEI, aLS,
aVertVa, aCoordVa, aCB, mySmartMap);
}
}
}// for (i=1; i<=aNb; ++i) {
@ -353,6 +358,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
//=======================================================================
void Path (const GeomAdaptor_Surface& aGAS,
const TopoDS_Face& myFace,
const MyDataMapOfShapeBoolean& aVertMap,
const TopoDS_Vertex& aVFirst,
const TopoDS_Edge& aEFirst,
BOPAlgo_EdgeInfo& aEIFirst,
@ -360,13 +366,12 @@ void Path (const GeomAdaptor_Surface& aGAS,
TopTools_SequenceOfShape& aVertVa,
TColgp_SequenceOfPnt2d& aCoordVa,
BOPTools_ConnexityBlock& aCB,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
MyDataMapOfShapeBoolean aVertMap)
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
{
Standard_Integer i, j, aNb, aNbj;
Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
Standard_Boolean anIsSameV2d, anIsSameV, anIsOut, anIsNotPassed;
Standard_Boolean bIsClosed;
TopoDS_Vertex aVa, aVb;
TopoDS_Edge aEOuta;
@ -378,6 +383,8 @@ void Path (const GeomAdaptor_Surface& aGAS,
BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
//
aTwoPI = M_PI + M_PI;
NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeq;
//
// append block
//
@ -394,6 +401,7 @@ void Path (const GeomAdaptor_Surface& aGAS,
anEdgeInfo->SetPassed(Standard_True);
aLS.Append(aEOuta);
aVertVa.Append(aVa);
anInfoSeq.Append (anEdgeInfo);
TopoDS_Vertex pVa=aVa;
pVa.Orientation(TopAbs_FORWARD);
@ -474,6 +482,7 @@ void Path (const GeomAdaptor_Surface& aGAS,
//
TopTools_SequenceOfShape aLSt, aVertVat;
TColgp_SequenceOfPnt2d aCoordVat;
NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeqTmp;
//
aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
//
@ -481,15 +490,16 @@ void Path (const GeomAdaptor_Surface& aGAS,
aLSt.Append(aLS(j));
aVertVat.Append(aVertVa(j));
aCoordVat.Append(aCoordVa(j));
anInfoSeqTmp.Append (anInfoSeq (j));
}
//
aLS.Clear();
aVertVa.Clear();
aCoordVa.Clear();
aLS=aLSt;
aVertVa=aVertVat;
aCoordVa=aCoordVat;
anInfoSeq = anInfoSeqTmp;
aEOuta = TopoDS::Edge (aLS.Last());
anEdgeInfo = anInfoSeq.Last();
//
break;
}
@ -501,8 +511,12 @@ void Path (const GeomAdaptor_Surface& aGAS,
//
anAngleIn = AngleIn(aEOuta, aLEInfo);
aMinAngle = 100.;
anIsFound = Standard_False;
Standard_Integer iCnt = NbWaysOut(aLEInfo);
Standard_Boolean isBoundary = !anEdgeInfo->IsInside();
Standard_Integer aNbWaysInside = 0;
BOPAlgo_EdgeInfo *pOnlyWayIn = NULL;
Standard_Integer aCurIndexE = 0;
anIt.Initialize(aLEInfo);
for (; anIt.More(); anIt.Next()) {
@ -525,7 +539,6 @@ void Path (const GeomAdaptor_Surface& aGAS,
if (iCnt==1) {
// the one and only way to go out .
pEdgeInfo=&anEI;
anIsFound=Standard_True;
break;
}
//
@ -548,15 +561,25 @@ void Path (const GeomAdaptor_Surface& aGAS,
anAngleOut=anEI.Angle();
anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
}
if (isBoundary && anEI.IsInside())
{
++aNbWaysInside;
pOnlyWayIn = &anEI;
}
if (anAngle < aMinAngle - eps) {
aMinAngle=anAngle;
pEdgeInfo=&anEI;
anIsFound=Standard_True;
}
}
} // for (; anIt.More(); anIt.Next())
if (aNbWaysInside == 1)
{
pEdgeInfo = pOnlyWayIn;
}
//
if (!anIsFound) {
if (!pEdgeInfo) {
// no way to go . (Error)
return;
}
@ -860,48 +883,15 @@ Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
//purpose :
//=======================================================================
void RefineAngles(const TopoDS_Face& myFace,
const TopTools_ListOfShape& myEdges,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
const Handle(IntTools_Context)& theContext)
{
Standard_Integer aNb, i;
NCollection_IndexedDataMap<TopoDS_Shape,
Standard_Integer,
TopTools_ShapeMapHasher> aMSI;
TopTools_MapOfShape aMBE;
TopTools_ListIteratorOfListOfShape aIt;
//
// 1. Boundary Edges
aIt.Initialize(myEdges);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aE=aIt.Value();
if(aMSI.Contains(aE)) {
Standard_Integer& iCnt = aMSI.ChangeFromKey(aE);
++iCnt;
}
else {
Standard_Integer iCnt = 1;
aMSI.Add(aE, iCnt);
}
}
//
aNb = aMSI.Extent();
for (i = 1; i <= aNb; ++i) {
Standard_Integer iCnt = aMSI(i);
if (iCnt == 1) {
const TopoDS_Shape& aE = aMSI.FindKey(i);
aMBE.Add(aE);
}
}
//
aMSI.Clear();
//
aNb = mySmartMap.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&mySmartMap.FindKey(i));
BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
//
RefineAngles(aV, myFace, aMBE, aLEI, theContext);
const Standard_Integer aNb = mySmartMap.Extent();
for (Standard_Integer i = 1; i <= aNb; ++i)
{
const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&mySmartMap.FindKey (i));
BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap (i);
RefineAngles(aV, myFace, aLEI, theContext);
}
}
//=======================================================================
@ -917,7 +907,6 @@ typedef TopTools_DataMapOfShapeReal::Iterator \
//=======================================================================
void RefineAngles(const TopoDS_Vertex& aV,
const TopoDS_Face& myFace,
const TopTools_MapOfShape& aMBE,
BOPAlgo_ListOfEdgeInfo& aLEI,
const Handle(IntTools_Context)& theContext)
{
@ -934,11 +923,10 @@ void RefineAngles(const TopoDS_Vertex& aV,
aItLEI.Initialize(aLEI);
for (; aItLEI.More(); aItLEI.Next()) {
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
const TopoDS_Edge& aE=aEI.Edge();
bIsIn=aEI.IsIn();
aA=aEI.Angle();
//
if (aMBE.Contains(aE)) {
if (!aEI.IsInside()) {
++iCntBnd;
if (!bIsIn) {
aA1=aA;
@ -962,7 +950,7 @@ void RefineAngles(const TopoDS_Vertex& aV,
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
const TopoDS_Edge& aE=aEI.Edge();
//
bIsBoundary=aMBE.Contains(aE);
bIsBoundary=!aEI.IsInside();
bIsIn=aEI.IsIn();
if (bIsBoundary || bIsIn) {
continue;

View File

@ -1636,7 +1636,7 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
TopoDS_Edge& theE)
{
BRep_Builder aBB;
Standard_Real aNeedTol = theTolR3D + 1e-12;
Standard_Real aNeedTol = theTolR3D + BOPTools_AlgoTools::DTolerance();
//
aBB.UpdateVertex(theV1, aNeedTol);
aBB.UpdateVertex(theV2, aNeedTol);

View File

@ -32,6 +32,7 @@
#include <TopAbs_ShapeEnum.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_ListOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <Precision.hxx>
@ -60,6 +61,15 @@ public:
DEFINE_STANDARD_ALLOC
public: //! @name Constants
//! Additional tolerance (delta tolerance) is used in Boolean Operations
//! to ensure that the tolerance of new/old entities obtained
//! by intersection of two shapes is slightly bigger than the actual
//! distances to these shapes. It helps to avoid numerical instability
//! which may occur when comparing distances and tolerances.
static Standard_Real DTolerance() { return 1.e-12; }
public: //! @name Intersection of the vertices
//! Intersects the vertex <theV1> with the point <theP> with tolerance <theTolP>.
@ -552,9 +562,22 @@ public: //! @name Other methods
const TopoDS_Edge& aE,
const Handle(IntTools_Context)& aContext);
//! Retutns dimension of the shape <theS>.
//! Returns the min and max dimensions of the shape <theS>.
Standard_EXPORT static void Dimensions (const TopoDS_Shape& theS,
Standard_Integer& theDMin,
Standard_Integer& theDMax);
//! Returns dimension of the shape <theS>.
//! If the shape contains elements of different dimension, -1 is returned.
Standard_EXPORT static Standard_Integer Dimension(const TopoDS_Shape& theS);
//! Collects in the output list recursively all non-compound sub-shapes of the first level
//! of the given shape theS. The optional map theMap is used to avoid the duplicates in the
//! output list, so it will also contain all non-compound sub-shapes.
Standard_EXPORT static void TreatCompound (const TopoDS_Shape& theS,
TopTools_ListOfShape& theList,
TopTools_MapOfShape* theMap = NULL);
//! Returns true if the shell <theShell> is open
Standard_EXPORT static Standard_Boolean IsOpenShell(const TopoDS_Shell& theShell);

View File

@ -525,6 +525,7 @@ namespace {
struct EdgeData {
const TopoDS_Edge* Edge; // Edge
Standard_Real VParameter; // Parameter of the vertex on the edge
Standard_Boolean IsClosed; // Closed flag of the edge
Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
Standard_Real First; // First parameter in the range
Standard_Real Last; // Last parameter in the rage
@ -610,9 +611,9 @@ static
continue;
}
//
if (Abs(aTint1 - aT1) > aHalfR1 ||
Abs(aTint2 - aT2) > aHalfR2) {
// intersection on the other end of the closed edge
if ((!theEData1.IsClosed && Abs (aTint1 - aT1) > aHalfR1) ||
(!theEData2.IsClosed && Abs (aTint2 - aT2) > aHalfR2)) {
// intersection is on the other end of the edge
continue;
}
//
@ -634,7 +635,7 @@ void CorrectWires(const TopoDS_Face& aFx,
const TopTools_IndexedMapOfShape& aMapToAvoid)
{
Standard_Integer i, aNbV;
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2;
gp_Pnt aP, aPV;
gp_Pnt2d aP2D;
TopoDS_Face aF;
@ -644,11 +645,9 @@ void CorrectWires(const TopoDS_Face& aFx,
aF=aFx;
aF.Orientation(TopAbs_FORWARD);
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
//
TopExp::MapShapesAndAncestors(aF,
TopAbs_VERTEX,
TopAbs_EDGE,
aMVE);
TopExp::MapShapesAndUniqueAncestors (aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE, Standard_True);
NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
aNbV=aMVE.Extent();
for (i=1; i<=aNbV; ++i) {
@ -666,7 +665,13 @@ void CorrectWires(const TopoDS_Face& aFx,
const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
const Handle(Geom2d_Curve)& aC2D=
BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
aT=BRep_Tool::Parameter(aV, aE);
Standard_Real aT = BRep_Tool::Parameter (aV, aE);
Standard_Boolean isClosed = Standard_False;
{
TopoDS_Vertex aV1, aV2;
TopExp::Vertices (aE, aV1, aV2);
isClosed = aV1.IsSame (aV2);
}
//
aC2D->D0(aT, aP2D);
aS->D0(aP2D.X(), aP2D.Y(), aP);
@ -674,7 +679,7 @@ void CorrectWires(const TopoDS_Face& aFx,
if (aD2>aD2max) {
aD2max=aD2;
}
EdgeData anEData = {&aE, aT, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
EdgeData anEData = {&aE, aT, isClosed, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
aLEPars.Append(anEData);
}
//
@ -818,7 +823,7 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
Standard_Boolean SameRange = TE->SameRange();
Standard_Real First = myHCurve->FirstParameter();
Standard_Real Last = myHCurve->LastParameter();
Standard_Real Delta =1.e-12;
Standard_Real Delta = BOPTools_AlgoTools::DTolerance();
Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
const TopLoc_Location& Floc = S.Location();

View File

@ -34,10 +34,6 @@
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
static
void TreatCompound(const TopoDS_Shape& theC1,
TopTools_ListOfShape& theLSX);
//=======================================================================
// function: UpdateVertex
// purpose:
@ -46,7 +42,7 @@ void BOPTools_AlgoTools::UpdateVertex
(const TopoDS_Vertex& aVF,
const TopoDS_Vertex& aNewVertex)
{
Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
Standard_Real aTolVF, aTolNewVertex, aDist, aNewTol;
//
gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
@ -58,7 +54,7 @@ void BOPTools_AlgoTools::UpdateVertex
if (aNewTol>aTolVF) {
BRep_Builder BB;
BB.UpdateVertex (aVF, aNewTol+aDTol);
BB.UpdateVertex (aVF, aNewTol + BOPTools_AlgoTools::DTolerance());
}
}
@ -70,7 +66,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
Standard_Real aTolV, aDist, aFirst, aLast;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
@ -81,7 +77,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist+aDTol);
BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
}
}
//
@ -93,7 +89,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
Standard_Real aTolV, aDist, aDTol=1.e-12;
Standard_Real aTolV, aDist;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
@ -104,7 +100,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist+aDTol);
BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
}
}
//=======================================================================
@ -269,7 +265,7 @@ void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
const TopoDS_Face& aF1,
TopoDS_Vertex& aNewVertex)
{
Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12;
Standard_Real aTol1, aTol2, aMaxTol;
gp_Pnt aPnt;
PointOnEdge (aE1, aParm1, aPnt);
@ -277,8 +273,7 @@ void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
aTol1=BRep_Tool::Tolerance(aE1);
aTol2=BRep_Tool::Tolerance(aF1);
//
//aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
aMaxTol=aTol1+aTol2+delta;
aMaxTol = aTol1 + aTol2 + BOPTools_AlgoTools::DTolerance();
//
BRep_Builder aBB;
aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
@ -437,103 +432,101 @@ void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE,
}
}
}
namespace
{
//=======================================================================
//function : dimension
//purpose : returns dimension of elementary shape
//=======================================================================
static Standard_Integer dimension (const TopoDS_Shape& theS)
{
switch (theS.ShapeType())
{
case TopAbs_VERTEX:
return 0;
case TopAbs_EDGE:
case TopAbs_WIRE:
return 1;
case TopAbs_FACE:
case TopAbs_SHELL:
return 2;
case TopAbs_SOLID:
case TopAbs_COMPSOLID:
return 3;
default:
return -1;
}
}
}
//=======================================================================
//function : Dimensions
//purpose :
//=======================================================================
void BOPTools_AlgoTools::Dimensions (const TopoDS_Shape& theS,
Standard_Integer& theDMin,
Standard_Integer& theDMax)
{
theDMin = theDMax = dimension (theS);
if (theDMax >= 0)
return;
TopTools_ListOfShape aLS;
TopTools_MapOfShape aMFence;
TreatCompound (theS, aLS, &aMFence);
if (aLS.IsEmpty())
{
// empty shape
theDMin = theDMax = -1;
return;
}
theDMin = 3;
theDMax = 0;
for (TopTools_ListOfShape::Iterator it (aLS); it.More(); it.Next())
{
Standard_Integer aDim = dimension (it.Value());
if (aDim < theDMin)
theDMin = aDim;
if (aDim > theDMax)
theDMax = aDim;
}
}
//=======================================================================
//function : Dimension
//purpose :
//=======================================================================
Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
{
Standard_Integer i, iRet, iRx0 = 0, iRx = 0;
TopAbs_ShapeEnum aTS;
TopTools_ListOfShape aLS;
TopTools_ListIteratorOfListOfShape aIt;
//
aTS=theS.ShapeType();
if (aTS!=TopAbs_COMPOUND) {
switch (aTS) {
case TopAbs_EDGE:
case TopAbs_WIRE:
iRet=1;
break;
case TopAbs_FACE:
case TopAbs_SHELL:
iRet=2;
break;
case TopAbs_SOLID:
case TopAbs_COMPSOLID:
iRet=3;
break;
default:
iRet=0;
}
return iRet;
}
//
iRet=-1;
TreatCompound(theS, aLS);
if(aLS.IsEmpty()) {
iRet = -2; //empty compound
return iRet;
}
aIt.Initialize(aLS);
for (i=0; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSx=aIt.Value();
iRx=Dimension(aSx);
if (!i) {
iRx0=iRx;
i=1;
continue;
}
if (iRx!=iRx0) {
return iRet;// -1
}
}
return iRx;
Standard_Integer aDMin, aDMax;
Dimensions (theS, aDMin, aDMax);
return (aDMin == aDMax) ? aDMin : -1;
}
//=======================================================================
//function : TreatCompound
//purpose :
//=======================================================================
void TreatCompound(const TopoDS_Shape& theC1,
TopTools_ListOfShape& theLSX)
void BOPTools_AlgoTools::TreatCompound (const TopoDS_Shape& theS,
TopTools_ListOfShape& theLS,
TopTools_MapOfShape* theMFence)
{
Standard_Integer aNbC1;
TopAbs_ShapeEnum aType;
TopTools_ListOfShape aLC, aLC1;
TopTools_ListIteratorOfListOfShape aIt, aIt1;
TopoDS_Iterator aItC;
//
aLC.Append (theC1);
for(;;) {
aLC1.Clear();
aIt.Initialize(aLC);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aC=aIt.Value(); //C is compound
//
aItC.Initialize(aC);
for (; aItC.More(); aItC.Next()) {
const TopoDS_Shape& aS=aItC.Value();
aType=aS.ShapeType();
if (aType==TopAbs_COMPOUND) {
aLC1.Append(aS);
}
else {
theLSX.Append(aS);
}
}
TopAbs_ShapeEnum aType = theS.ShapeType();
if (aType != TopAbs_COMPOUND)
{
if (!theMFence || theMFence->Add (theS))
{
theLS.Append (theS);
}
//
aNbC1=aLC1.Extent();
if (!aNbC1) {
break;
}
//
aLC.Clear();
aIt.Initialize(aLC1);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSC=aIt.Value();
aLC.Append(aSC);
}
}// while(1)
return;
}
for (TopoDS_Iterator it (theS); it.More(); it.Next())
{
TreatCompound (it.Value(), theLS, theMFence);
}
}

View File

@ -285,14 +285,7 @@ void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer,
aSelectorLine.SetCurrentLine(L, Par);
Standard_Integer SelsEVL = 0;
SelsEVL = aTree.Select(aSelectorLine); //SelsEE > 0 => Line/Edges & Line/Vertex intersection
if (!aSelectorLine.IsCorrect())
{
// Go to the next segment
isFaultyLine = Standard_True;
continue;
}
if (SelsEVL > 0 )
{
// Line and edges / vertices interference.

View File

@ -70,6 +70,12 @@ public:
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! Set value of hang checking flag
//! if this flag = true, possible hang of algorithm is checked
//! and algorithm is forced to stop.
//! By default hang checking is used.
Standard_EXPORT void SetHangChecking(const Standard_Boolean theHangChecking);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@ -125,6 +131,7 @@ private:
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
Standard_Boolean myHangChecking;
};

View File

@ -31,6 +31,7 @@
#include <BRepFill_FaceAndOrder.hxx>
#include <BRepFill_Filling.hxx>
#include <BRepLib.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepLib_MakeEdge.hxx>
#include <BRepLib_MakeEdge2d.hxx>
#include <BRepLib_MakeFace.hxx>
@ -234,8 +235,6 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
if (IsBound)
{
myBoundary.Append( EdgeFaceAndOrder );
TopTools_ListOfShape EmptyList;
myOldNewMap.Bind(anEdge, EmptyList);
return myBoundary.Length();
}
else
@ -258,8 +257,6 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
if (IsBound)
{
myBoundary.Append( EdgeFaceAndOrder );
TopTools_ListOfShape EmptyList;
myOldNewMap.Bind(anEdge, EmptyList);
return myBoundary.Length();
}
else
@ -460,7 +457,9 @@ void BRepFill_Filling::BuildWires( TopTools_ListOfShape& EdgeList, TopTools_List
aDist < BRep_Tool::Tolerance(V_edge[j]))
{
MW.Add(CurEdge);
myOldNewMap(CurEdge).Append(MW.Edge());
TopoDS_Edge NewEdge = MW.Edge();
myOldNewMap.Bind(CurEdge.Oriented(TopAbs_FORWARD),
NewEdge.Oriented(TopAbs_FORWARD));
EdgeList.Remove(Itl);
found = Standard_True;
break;
@ -704,25 +703,47 @@ void BRepFill_Filling::Build()
{
const TopoDS_Edge& InitEdge = myBoundary(i).myEdge;
TopoDS_Edge anEdge = InitEdge;
if (!myOldNewMap(anEdge).IsEmpty())
anEdge = TopoDS::Edge( myOldNewMap(anEdge).First() );
anEdge.Orientation(TopAbs_FORWARD);
if (myOldNewMap.IsBound(anEdge))
anEdge = TopoDS::Edge(myOldNewMap(anEdge));
Handle(Geom2d_Curve) aCurveOnPlate = CurvesOnPlate->Value(i);
TopoDS_Edge NewEdge = TopoDS::Edge(anEdge.EmptyCopied());
TopoDS_Vertex V1, V2;
TopExp::Vertices(anEdge, V1, V2, Standard_True); //with orientation
BB.UpdateVertex(V1, dmax);
BB.UpdateVertex(V2, dmax);
BB.Add(NewEdge, V1);
BB.Add(NewEdge, V2);
TopoDS_Vertex V1, V2, NewV1, NewV2;
TopExp::Vertices(anEdge, V1, V2);
if (myOldNewMap.IsBound(V1))
NewV1 = TopoDS::Vertex(myOldNewMap(V1));
else
{
gp_Pnt aPnt = BRep_Tool::Pnt(V1);
NewV1 = BRepLib_MakeVertex(aPnt);
BB.UpdateVertex(NewV1, dmax);
myOldNewMap.Bind(V1.Oriented(TopAbs_FORWARD), NewV1);
}
if (myOldNewMap.IsBound(V2))
NewV2 = TopoDS::Vertex(myOldNewMap(V2));
else
{
gp_Pnt aPnt = BRep_Tool::Pnt(V2);
NewV2 = BRepLib_MakeVertex(aPnt);
BB.UpdateVertex(NewV2, dmax);
myOldNewMap.Bind(V2.Oriented(TopAbs_FORWARD), NewV2);
}
NewV1.Orientation(TopAbs_FORWARD);
BB.Add(NewEdge, NewV1);
NewV2.Orientation(TopAbs_REVERSED);
BB.Add(NewEdge, NewV2);
TopLoc_Location Loc;
BB.UpdateEdge(NewEdge, aCurveOnPlate, Surface, Loc, dmax);
//BRepLib::SameRange(NewEdge);
BRepLib::SameParameter(NewEdge, dmax, Standard_True);
FinalEdges.Append(NewEdge);
myOldNewMap(InitEdge).Clear();
myOldNewMap(InitEdge).Append(NewEdge);
myOldNewMap.Bind(InitEdge.Oriented(TopAbs_FORWARD), NewEdge.Oriented(TopAbs_FORWARD));
}
TopoDS_Wire FinalWire = WireFromList(FinalEdges);

View File

@ -25,7 +25,7 @@
#include <BRepFill_SequenceOfEdgeFaceAndOrder.hxx>
#include <BRepFill_SequenceOfFaceAndOrder.hxx>
#include <GeomPlate_SequenceOfPointConstraint.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS_Face.hxx>
#include <Standard_Real.hxx>
@ -207,7 +207,7 @@ private:
BRepFill_SequenceOfEdgeFaceAndOrder myConstraints;
BRepFill_SequenceOfFaceAndOrder myFreeConstraints;
GeomPlate_SequenceOfPointConstraint myPoints;
TopTools_DataMapOfShapeListOfShape myOldNewMap;
TopTools_DataMapOfShapeShape myOldNewMap;
TopTools_ListOfShape myGenerated;
TopoDS_Face myFace;
TopoDS_Face myInitFace;

View File

@ -451,7 +451,12 @@ void BRepFill_LocationLaw::CurvilinearBounds(const Standard_Integer Index,
Standard_Boolean BRepFill_LocationLaw::IsClosed() const
{
return myPath.Closed();
if (myPath.Closed())
return Standard_True;
TopoDS_Vertex V1, V2;
TopExp::Vertices(myPath, V1, V2);
return (V1.IsSame(V2));
}
//=======================================================================

View File

@ -105,20 +105,15 @@ static Handle(Geom_BSplineCurve) EdgeToBSpline (const TopoDS_Edge& theEdge)
Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aLoc, aFirst, aLast);
// convert its part used by edge to bspline; note that if edge curve is bspline,
// conversion made via trimmed curve is still needed -- it will copy it, segment
// as appropriate, and remove periodicity if it is periodic (deadly for approximator)
// approximation or conversion made via trimmed curve is still needed -- it will copy it,
// segment as appropriate, and remove periodicity if it is periodic (deadly for approximator)
Handle(Geom_TrimmedCurve) aTrimCurve = new Geom_TrimmedCurve (aCurve, aFirst, aLast);
// special treatment of conic curve
if (aTrimCurve->BasisCurve()->IsKind(STANDARD_TYPE(Geom_Conic)))
{
const Handle(Geom_Curve)& aCurveTemp = aTrimCurve; // to avoid ambiguity
GeomConvert_ApproxCurve anAppr (aCurveTemp, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (anAppr.HasResult())
aBSCurve = anAppr.Curve();
}
const Handle(Geom_Curve)& aCurveTemp = aTrimCurve; // to avoid ambiguity
GeomConvert_ApproxCurve anAppr (aCurveTemp, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (anAppr.HasResult())
aBSCurve = anAppr.Curve();
// general case
if (aBSCurve.IsNull())
aBSCurve = GeomConvert::CurveToBSplineCurve (aTrimCurve);

View File

@ -1377,7 +1377,7 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
BB.Add(aWire, CurEdge);
} //for (jj = 2; jj <= SeqEdges.Length(); jj++)
//case of closed wire
if (mySection->IsVClosed() &&
if (myLocation->IsClosed() &&
!CurVertex.IsSame(FirstVertex))
{
const TopTools_ListOfShape& Elist = VEmap.FindFromKey(CurVertex);

View File

@ -1831,6 +1831,12 @@ void BRepLib::UpdateInnerTolerances(const TopoDS_Shape& aShape)
for (Standard_Integer i = 1; i <= EFmap.Extent(); i++)
{
TopoDS_Edge anEdge = TopoDS::Edge(EFmap.FindKey(i));
if (!BRep_Tool::IsGeometric(anEdge))
{
continue;
}
TopoDS_Vertex V1, V2;
TopExp::Vertices(anEdge, V1, V2);
Standard_Real fpar, lpar;

View File

@ -252,7 +252,21 @@ void BRepPrimAPI_MakeRevol::Build()
static Standard_Boolean IsIntersect(const Handle(Adaptor3d_HCurve)& theC,
const gp_Ax1& theAxe)
{
const Handle(Geom_Line) aL = new Geom_Line(theAxe);
const gp_Lin anAxis(theAxe);
//Quick test for circle
if (theC->GetType() == GeomAbs_Circle)
{
gp_Circ aCirc = theC->Circle();
const gp_Pnt& aCentr = aCirc.Location();
Standard_Real anR2 = aCirc.Radius();
anR2 -= Precision::Confusion();
anR2 *= anR2;
if (anAxis.SquareDistance(aCentr) > anR2)
{
return Standard_False;
}
}
const Handle(Geom_Line) aL = new Geom_Line(anAxis);
const GeomAdaptor_Curve aLin(aL);
const Standard_Real aParTol = theC->Resolution(Precision::Confusion());
const Standard_Real aParF = theC->FirstParameter() + aParTol,

View File

@ -523,8 +523,10 @@ TopoDS_Shape BRepSweep_NumLinearRegularSweep::SplitShell(const TopoDS_Shape& aNe
Standard_Boolean BRepSweep_NumLinearRegularSweep::IsUsed(const TopoDS_Shape& aGenS) const
{
Standard_Integer iGenS = myGenShapeTool.Index(aGenS);
Standard_OutOfRange_Raise_if(iGenS == 0,
"BRepSweep_NumLinearRegularSweep::IsUsed: shape index = 0")
if (iGenS == 0)
{
return Standard_False;
}
Standard_Integer j;
Standard_Boolean isBuilt = Standard_False;
Standard_Boolean isUsed = Standard_False;
@ -576,7 +578,16 @@ Standard_Boolean BRepSweep_NumLinearRegularSweep::IsUsed(const TopoDS_Shape& aGe
Standard_Boolean BRepSweep_NumLinearRegularSweep::GenIsUsed(const TopoDS_Shape& aGenS) const
{
Standard_Integer iGenS = myGenShapeTool.Index(aGenS);
Standard_OutOfRange_Raise_if(iGenS == 0,
"BRepSweep_NumLinearRegularSweep::GenIsUsed: shape index = 0")
return myBuiltShapes(iGenS, 1) && myUsedShapes(iGenS, 1);
if (iGenS == 0)
{
return Standard_False;
}
if (iGenS == 1)
{
return myBuiltShapes(iGenS, 1);
}
else
{
return myBuiltShapes(iGenS, 1) && myUsedShapes(iGenS, 1);
}
}

View File

@ -97,6 +97,7 @@
#include <Geom2d_TrimmedCurve.hxx>
#include <GeomConvert_ApproxSurface.hxx>
#include <BRepTest_Objects.hxx>
#include <stdio.h>
#include <gp_Pnt.hxx>
@ -452,13 +453,18 @@ static Standard_Integer approxplate (Draw_Interpretor & di,Standard_Integer n,co
static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, const char** a )
{
#ifdef OCCT_DEBUG
// Chronmetrage
// Chronometrage
OSD_Chronometer Chrono;
Chrono.Reset();
Chrono.Start();
#endif
if (n < 7) return 1;
if (n < 7)
{
di.PrintHelp(a[0]);
return 1;
}
Standard_Integer NbBounds = Draw::Atoi( a[2] );
Standard_Integer NbConstraints = Draw::Atoi( a[3] );
Standard_Integer NbPoints = Draw::Atoi( a[4] );
@ -473,8 +479,6 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
TolCurv,
MaxDeg,
MaxSegments );
//TopoDS_Shape aLocalFace(DBRep::Get( a[5], TopAbs_FACE ) );
//TopoDS_Face InitFace = TopoDS::Face( aLocalFace);
TopoDS_Face InitFace = TopoDS::Face( DBRep::Get(a[5], TopAbs_FACE) );
if (! InitFace.IsNull())
MakeFilling.LoadInitSurface( InitFace );
@ -484,104 +488,94 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
TopoDS_Face F;
gp_Pnt Point;
Standard_Integer Order;
TopTools_ListOfShape ListForHistory;
for (k = 1; k <= NbBounds; k++)
{
E.Nullify();
F.Nullify();
//TopoDS_Shape aLocalEdge(DBRep::Get( a[i], TopAbs_EDGE ));
//E = TopoDS::Edge(aLocalEdge);
E = TopoDS::Edge( DBRep::Get(a[i], TopAbs_EDGE) );
if (! E.IsNull())
i++;
//aLocalFace = DBRep::Get( a[i], TopAbs_FACE ) ;
//F = TopoDS::Face(aLocalFace);
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (! E.IsNull() && ! F.IsNull())
MakeFilling.Add( E, F, (GeomAbs_Shape)Order );
else if (E.IsNull())
{
if (F.IsNull())
{
//std::cout<<std::endl<<"Wrong parameters"<<std::endl<<std::endl;
di<<"\nWrong parameters\n\n";
return 1;
}
else
MakeFilling.Add( F, (GeomAbs_Shape)Order );
}
else
MakeFilling.Add( E, (GeomAbs_Shape)Order );
}
for (k = 1; k <= NbConstraints; k++)
{
E.Nullify();
F.Nullify();
//TopoDS_Shape aLocalEdge(DBRep::Get( a[i++], TopAbs_EDGE ));
//E = TopoDS::Edge( aLocalEdge);
E = TopoDS::Edge( DBRep::Get(a[i++], TopAbs_EDGE) );
if (E.IsNull())
{
//std::cout<<"Wrong parameters"<<std::endl;
di<<"Wrong parameters\n";
return 1;
}
//TopoDS_Shape alocalFace(DBRep::Get( a[i], TopAbs_FACE ) );
//F = TopoDS::Face( alocalFace);
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (F.IsNull())
MakeFilling.Add( E, (GeomAbs_Shape)Order, Standard_False );
else
MakeFilling.Add( E, F, (GeomAbs_Shape)Order, Standard_False );
}
for (k = 1; k <= NbPoints; k++)
{
E.Nullify();
F.Nullify();
E = TopoDS::Edge( DBRep::Get(a[i], TopAbs_EDGE) );
if (! E.IsNull())
i++;
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (! E.IsNull() && ! F.IsNull())
MakeFilling.Add( E, F, (GeomAbs_Shape)Order );
else if (E.IsNull())
{
if (DrawTrSurf::GetPoint( a[i], Point ))
{
MakeFilling.Add( Point );
i++;
}
if (F.IsNull())
{
di<<"\nWrong parameters\n\n";
return 1;
}
else
{
Standard_Real U = Draw::Atof( a[i++] ), V = Draw::Atof( a[i++] );
//aLocalFace = DBRep::Get( a[i++], TopAbs_FACE );
//F = TopoDS::Face( aLocalFace);
F = TopoDS::Face( DBRep::Get(a[i++], TopAbs_FACE));
if (F.IsNull())
{
//std::cout<<"Wrong parameters"<<std::endl;
di<<"Wrong parameters\n";
return 1;
}
Order = Draw::Atoi( a[i++] );
MakeFilling.Add( U, V, F, (GeomAbs_Shape)Order );
}
MakeFilling.Add( F, (GeomAbs_Shape)Order );
}
else
MakeFilling.Add( E, (GeomAbs_Shape)Order );
//History
if (!E.IsNull())
ListForHistory.Append(E);
}
for (k = 1; k <= NbConstraints; k++)
{
E.Nullify();
F.Nullify();
E = TopoDS::Edge( DBRep::Get(a[i++], TopAbs_EDGE) );
if (E.IsNull())
{
di<<"Wrong parameters\n";
return 1;
}
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (F.IsNull())
MakeFilling.Add( E, (GeomAbs_Shape)Order, Standard_False );
else
MakeFilling.Add( E, F, (GeomAbs_Shape)Order, Standard_False );
}
for (k = 1; k <= NbPoints; k++)
{
if (DrawTrSurf::GetPoint( a[i], Point ))
{
MakeFilling.Add( Point );
i++;
}
else
{
Standard_Real U = Draw::Atof( a[i++] ), V = Draw::Atof( a[i++] );
F = TopoDS::Face( DBRep::Get(a[i++], TopAbs_FACE));
if (F.IsNull())
{
di<<"Wrong parameters\n";
return 1;
}
Order = Draw::Atoi( a[i++] );
MakeFilling.Add( U, V, F, (GeomAbs_Shape)Order );
}
}
MakeFilling.Build();
if (! MakeFilling.IsDone())
{
//std::cout<<"filling failed"<<std::endl;
di<<"filling failed\n";
return 0;
}
{
di<<"filling failed\n";
return 0;
}
Standard_Real dmax = MakeFilling.G0Error(),
angmax = MakeFilling.G1Error(),
curvmax = MakeFilling.G2Error();
//std::cout<<" dist. max = "<<dmax<<" ; angle max = "<<angmax<<" ; diffcurv max = "<<curvmax<<std::endl;
angmax = MakeFilling.G1Error(),
curvmax = MakeFilling.G2Error();
di<<" dist. max = "<<dmax<<" ; angle max = "<<angmax<<" ; diffcurv max = "<<curvmax<<"\n";
TopoDS_Face ResFace= TopoDS::Face( MakeFilling.Shape() );
DBRep::Set( a[1], ResFace );
@ -589,12 +583,14 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
Chrono.Stop();
Standard_Real Tps;
Chrono.Show(Tps);
//std::cout<<"*** FIN DE FILLING ***"<<std::endl;
//std::cout<<"Temps de calcul : "<<Tps<<std::endl;
di<<"*** FIN DE FILLING ***\n";
di<<"Temps de calcul : "<<Tps<<"\n";
#endif
//History
if (BRepTest_Objects::IsHistoryNeeded())
BRepTest_Objects::SetHistory(ListForHistory, MakeFilling);
return 0;
}

View File

@ -247,6 +247,10 @@ static Standard_Integer geompipe(Draw_Interpretor&,
std::cout << "GeomFill_Pipe cannot make a surface" << std::endl;
return 1;
}
Standard_Real Accuracy = aPipe.ErrorOnSurf();
std::cout << "Accuracy of approximation = " << Accuracy << std::endl;
Handle(Geom_Surface) Sur = aPipe.Surface();
TopoDS_Face F;
if (!Sur.IsNull())

View File

@ -903,25 +903,61 @@ void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
//purpose :
//=======================================================================
Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& S,
const Standard_Real deflec)
Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& theShape,
const Standard_Real theLinDefl,
const Standard_Boolean theToCheckFreeEdges)
{
TopExp_Explorer exf, exe;
TopLoc_Location l;
Handle(Poly_Triangulation) T;
Handle(Poly_PolygonOnTriangulation) Poly;
for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) {
const TopoDS_Face& F = TopoDS::Face(exf.Current());
T = BRep_Tool::Triangulation(F, l);
if (T.IsNull() || (T->Deflection() > deflec))
TopExp_Explorer anEdgeIter;
TopLoc_Location aDummyLoc;
for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation (aFace, aDummyLoc);
if (aTri.IsNull()
|| aTri->Deflection() > theLinDefl)
{
return Standard_False;
for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
Poly = BRep_Tool::PolygonOnTriangulation(E, T, l);
if (Poly.IsNull()) return Standard_False;
}
for (anEdgeIter.Init (aFace, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTri, aDummyLoc);
if (aPoly.IsNull())
{
return Standard_False;
}
}
}
if (!theToCheckFreeEdges)
{
return Standard_True;
}
Handle(Poly_Triangulation) anEdgeTri;
for (anEdgeIter.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anEdgeIter.More(); anEdgeIter.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
const Handle(Poly_Polygon3D)& aPolygon = BRep_Tool::Polygon3D (anEdge, aDummyLoc);
if (!aPolygon.IsNull())
{
if (aPolygon->Deflection() > theLinDefl)
{
return Standard_False;
}
}
else
{
const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeTri, aDummyLoc);
if (aPoly.IsNull()
|| anEdgeTri.IsNull()
|| anEdgeTri->Deflection() > theLinDefl)
{
return Standard_False;
}
}
}
return Standard_True;
}

View File

@ -162,10 +162,18 @@ public:
//! refer to surfaces not belonging to any face of <S>
Standard_EXPORT static void RemoveUnusedPCurves (const TopoDS_Shape& S);
//! verifies that each face from the shape <S> has got
//! a triangulation with a deflection <= deflec and
//! the edges a discretisation on this triangulation.
Standard_EXPORT static Standard_Boolean Triangulation (const TopoDS_Shape& S, const Standard_Real deflec);
//! Verifies that each Face from the shape has got a triangulation with a deflection smaller or equal to specified one
//! and the Edges a discretization on this triangulation.
//! @param theShape [in] shape to verify
//! @param theLinDefl [in] maximum allowed linear deflection
//! @param theToCheckFreeEdges [in] if TRUE, then free Edges are required to have 3D polygon
//! @return FALSE if input Shape contains Faces without triangulation,
//! or that triangulation has worse (greater) deflection than specified one,
//! or Edges in Shape lack polygons on triangulation
//! or free Edges in Shape lack 3D polygons
Standard_EXPORT static Standard_Boolean Triangulation (const TopoDS_Shape& theShape,
const Standard_Real theLinDefl,
const Standard_Boolean theToCheckFreeEdges = Standard_False);
//! Returns True if the distance between the two
//! vertices is lower than their tolerance.

View File

@ -482,6 +482,8 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
}
return Standard_True;
}
//
GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
@ -490,6 +492,19 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
if(ProjOnCurve.IsDone()) {
Curve2d = ProjOnCurve.BSpline();
if (S->IsUPeriodic() || S->IsVPeriodic())
{
//Surface is periodic, checking curve2d domain
//Old domain
gp_Pnt2d aPf = C2d->Value(f2d);
//New domain
gp_Pnt2d aNewPf = Curve2d->Value(f2d);
gp_Vec2d aT(aNewPf, aPf);
if (aT.SquareMagnitude() > Precision::SquarePConfusion())
{
Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Translated(aT));
}
}
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{

View File

@ -553,7 +553,7 @@ void Extrema_ExtCC::PrepareParallelResult(const Standard_Real theUt11,
if ((aRange.Delta() > Precision::Angular()) &&
((aPar2 - aPar1) < Precision::Angular()))
{
aPar1 -= aPeriod;
aPar2 += aPeriod;
}
}
@ -562,11 +562,13 @@ void Extrema_ExtCC::PrepareParallelResult(const Standard_Real theUt11,
Standard_Real aMinSquareDist = RealLast();
aProjRng1.Add(aPar1 - M_PI);
aProjRng1.Add(aPar2 - M_PI);
for (Standard_Integer i = 0; i < 2; i++)
aProjRng1.Add(aPar1 - aPeriod);
aProjRng1.Add(aPar2 - aPeriod);
for (Standard_Integer i = 0; i < 3; i++)
{
// Repeat computation twice
// Repeat computation three times, shifting the range to PI on each step,
// to be able to find if the concentric arcs ranges are intersected in just one parameter
// (lower or upper boundary).
Bnd_Range aRng = aProjRng1;
aRng.Common(aRange);

View File

@ -329,6 +329,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
(const Handle(Geom_Surface)& Sr)
{
Standard_Real U1, U2, V1, V2;
Sr->Bounds (U1, U2, V1, V2);
Standard_Real UFirst = Min (U1, U2);
@ -380,7 +381,10 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
VFirst, VLast);
return SurfaceToBSplineSurface(aStrim);
}
//
//For cylinders, cones, spheres, toruses
const Standard_Boolean isUClosed = Abs((ULast - UFirst) - 2. * M_PI) <= Precision::PConfusion();
//
if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
TColgp_Array2OfPnt Poles (1, 2, 1, 2);
Poles (1, 1) = Strim->Value (U1, V1);
@ -409,7 +413,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
Handle(Geom_CylindricalSurface)::DownCast(Surf);
gp_Cylinder Cyl = TheElSurf->Cylinder();
if (Strim->IsUClosed()) {
if (isUClosed) {
Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
@ -425,7 +429,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
Handle(Geom_ConicalSurface) TheElSurf =
Handle(Geom_ConicalSurface)::DownCast(Surf);
gp_Cone Co = TheElSurf->Cone();
if (Strim->IsUClosed()) {
if (isUClosed) {
Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
@ -442,7 +446,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
Handle(Geom_SphericalSurface)::DownCast(Surf);
gp_Sphere Sph = TheElSurf->Sphere();
//OCC217
if (Strim->IsUClosed()) {
if (isUClosed) {
//if (Strim->IsVClosed()) {
//Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
@ -461,7 +465,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
Handle(Geom_ToroidalSurface)::DownCast(Surf);
gp_Torus Tr = TheElSurf->Torus();
if (Strim->IsUClosed()) {
if (isUClosed) {
Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
Standard_False);
TheSurface = BSplineSurfaceBuilder (Convert);

View File

@ -475,16 +475,16 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
gp_Vec Tangent, Normal, BN, cross;
TColStd_SequenceOfReal parameters;
TColStd_SequenceOfReal EvolAT;
Standard_Real Param = First, L, norm;
Standard_Real Param = First, LengthMin, L, norm;
Standard_Boolean isZero = Standard_True, isConst = Standard_True;
const Standard_Real minnorm = 1.e-16;
Standard_Integer i;
gp_Pnt PonC;
gp_Vec D1;
frenet->SetInterval(First, Last); //To have the rigth evaluation at bounds
frenet->SetInterval(First, Last); //To have right evaluation at bounds
GeomFill_SnglrFunc CS(myCurve);
BndLib_Add3dCurve::Add(CS, First, Last, 1.e-2, Boite);
LengthMin = Boite.GetGap()*1.e-4;
aT = gp_Vec(0, 0, 0);
aN = gp_Vec(0, 0, 0);
@ -541,21 +541,13 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
//Evaluate the Next step
CS.D1(Param, PonC, D1);
L = PonC.XYZ().Modulus()/2;
L = Max(PonC.XYZ().Modulus()/2, LengthMin);
norm = D1.Magnitude();
if (norm <= gp::Resolution())
{
//norm = 2.*gp::Resolution();
norm = minnorm;
if (norm < Precision::Confusion()) {
norm = Precision::Confusion();
}
currStep = L / norm;
if (currStep <= gp::Resolution()) //L = 0 => curvature = 0, linear segment
currStep = Step;
if (currStep < Precision::Confusion()) //too small step
currStep = Precision::Confusion();
if (currStep > Step) //too big step
currStep = Step;//default value
if (currStep > Step) currStep = Step;//default value
}
else
currStep /= 2; // Step too long !

View File

@ -153,6 +153,9 @@ static Standard_Integer sweep (Draw_Interpretor& di,
return 1;
}
Standard_Real Accuracy = Pipe.ErrorOnSurf();
di << "Accuracy of approximation = " << Accuracy << "\n";
DrawTrSurf::Set(a[1], Pipe.Surface());
return 0;
@ -223,6 +226,10 @@ static Standard_Integer tuyau (Draw_Interpretor& di,
di << "GeomFill_Pipe cannot make a surface\n";
return 1;
}
Standard_Real Accuracy = Pipe.ErrorOnSurf();
di << "Accuracy of approximation = " << Accuracy << "\n";
DrawTrSurf::Set(a[indice_path-1], Pipe.Surface());
return 0;

View File

@ -682,10 +682,14 @@ void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRange
aRj2.Range(aTj21, aTj22);
//
bCond = (fabs(aTi12 - aTj11) < dTR1) ||
(aTj11 > aTi11 && aTj11 < aTi12) ||
(aTi11 > aTj11 && aTi11 < aTj12) ||
(bSplit2 && (fabs(aTj12 - aTi11) < dTR1));
if (bCond && bSplit2) {
bCond = (fabs((Max(aTi22, aTj22) - Min(aTi21, aTj21)) -
((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2);
((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2) ||
(aTj21 > aTi21 && aTj21 < aTi22) ||
(aTi21 > aTj21 && aTi21 < aTj22);
}
//
if (bCond) {

View File

@ -196,7 +196,7 @@ protected: //! @name Protected methods performing the intersection
//! Checks if the edge is in the face really.
Standard_EXPORT Standard_Boolean IsCoincident();
private:
protected:
TopoDS_Edge myEdge;
TopoDS_Face myFace;

View File

@ -120,7 +120,7 @@ protected:
//! and surfaces is computed.
Standard_EXPORT void ComputeTolReached3d();
private:
protected:
Standard_Boolean myIsDone;
IntPatch_Intersection myIntersector;

View File

@ -67,6 +67,12 @@ Standard_Boolean MeshVS_SensitiveQuad::Matches (SelectBasics_SelectingVolumeMana
{
if (!theMgr.IsOverlapAllowed()) // check for inclusion
{
if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.Overlaps (myVertices[0], myVertices[1], myVertices[2], Select3D_TOS_INTERIOR, aDummy)
&& theMgr.Overlaps (myVertices[0], myVertices[2], myVertices[3], Select3D_TOS_INTERIOR, aDummy);
}
for (Standard_Integer aPntIdx = 0; aPntIdx < 4; ++aPntIdx)
{
if (!theMgr.Overlaps (myVertices[aPntIdx]))

View File

@ -1156,6 +1156,10 @@ void ProjLib_ComputeApprox::Perform
Approx_FitAndDivide2d Fit(Deg1, Deg2, myTolerance, aTol2d, Standard_True, aFistC, aLastC);
Fit.SetMaxSegments(aMaxSegments);
if (simplecase)
{
Fit.SetHangChecking(Standard_False);
}
Fit.Perform(F);
Standard_Real aNewTol2d = 0;

View File

@ -44,6 +44,9 @@
#include <Geom_Parabola.hxx>
#include <Geom_Hyperbola.hxx>
#include <Geom_Ellipse.hxx>
#include <GeomLib_Tool.hxx>
#include <math_Jacobi.hxx>
#include <math_Matrix.hxx>
@ -516,10 +519,7 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
gp_Ax2 Axis;
Standard_Real R1 =0., R2 =0.;
if ( Type != GeomAbs_Line) // on garde le parametrage
myKeepParam = Standard_True;
else // on prend le choix utilisateur.
myKeepParam = KeepParametrization;
myKeepParam = KeepParametrization;
switch ( Type) {
case GeomAbs_Line:
@ -648,12 +648,13 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
Standard_Real Tol2 = myTolerance*myTolerance;
if (VDx.SquareMagnitude() < Tol2 ||
VDy.SquareMagnitude() < Tol2 ) {
myIsApprox = Standard_True;
VDy.SquareMagnitude() < Tol2 ||
VDx.CrossSquareMagnitude(VDy) < Tol2) {
myIsApprox = Standard_True;
}
if (!myIsApprox &&
gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
if (!myIsApprox)
{
Dx = gp_Dir(VDx);
Dy = gp_Dir(VDy);
gp_Pnt O = Axis.Location();
@ -662,39 +663,89 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
gp_Pnt Py = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
Standard_Real Major = P.Distance(Px);
Standard_Real Minor = P.Distance(Py);
gp_Ax2 Axe( P, Dx^Dy,Dx);
if ( Abs( Major - Minor) < Precision::Confusion()) {
myType = GeomAbs_Circle;
gp_Circ Circ(Axe, Major);
GeomCirclePtr = new Geom_Circle(Circ);
if (myKeepParam)
myIsApprox = !gp_Dir(VDx).IsNormal(gp_Dir(VDy), Precision::Angular());
else
{
// Since it is not necessary to keep the same parameter for the point on the original and on the projected curves,
// we will use the following approach to find axes of the projected ellipse and provide the canonical curve:
// https://www.geometrictools.com/Documentation/ParallelProjectionEllipse.pdf
math_Matrix aMatrA(1, 2, 1, 2);
// A = Jp^T * Pr(Je), where
// Pr(Je) - projection of axes of original ellipse to the target plane
// Jp - X and Y axes of the target plane
aMatrA(1, 1) = myPlane.XDirection().XYZ().Dot(VDx.XYZ());
aMatrA(1, 2) = myPlane.XDirection().XYZ().Dot(VDy.XYZ());
aMatrA(2, 1) = myPlane.YDirection().XYZ().Dot(VDx.XYZ());
aMatrA(2, 2) = myPlane.YDirection().XYZ().Dot(VDy.XYZ());
math_Matrix aMatrDelta2(1, 2, 1, 2, 0.0);
// | 1/MajorRad^2 0 |
// Delta^2 = | |
// | 0 1/MajorRad^2 |
aMatrDelta2(1, 1) = 1.0 / (R1 * R1);
aMatrDelta2(2, 2) = 1.0 / (R2 * R2);
math_Matrix aMatrAInv = aMatrA.Inverse();
math_Matrix aMatrM = aMatrAInv.Transposed() * aMatrDelta2 * aMatrAInv;
// perform eigenvalues calculation
math_Jacobi anEigenCalc(aMatrM);
if (anEigenCalc.IsDone())
{
// radii of the projected ellipse
Minor = 1.0 / Sqrt(anEigenCalc.Value(1));
Major = 1.0 / Sqrt(anEigenCalc.Value(2));
// calculate the rotation angle for the plane axes to meet the correct axes of the projected ellipse
// (swap eigenvectors in respect to major and minor axes)
const math_Matrix& anEigenVec = anEigenCalc.Vectors();
gp_Trsf2d aTrsfInPlane;
aTrsfInPlane.SetValues(anEigenVec(1, 2), anEigenVec(1, 1), 0.0,
anEigenVec(2, 2), anEigenVec(2, 1), 0.0);
gp_Trsf aRot;
aRot.SetRotation(gp_Ax1(P, myPlane.Direction()), aTrsfInPlane.RotationPart());
Dx = myPlane.XDirection().Transformed(aRot);
Dy = myPlane.YDirection().Transformed(aRot);
}
else
myIsApprox = Standard_True;
}
if (!myIsApprox)
{
gp_Ax2 Axe(P, Dx^Dy, Dx);
if (Abs(Major - Minor) < Precision::Confusion()) {
myType = GeomAbs_Circle;
gp_Circ Circ(Axe, Major);
GeomCirclePtr = new Geom_Circle(Circ);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
GeomAdaptor_Curve aGACurve(GeomCirclePtr);
myResult = new GeomAdaptor_HCurve(aGACurve);
GeomAdaptor_Curve aGACurve(GeomCirclePtr);
myResult = new GeomAdaptor_HCurve(aGACurve);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
}
else if ( Major > Minor) {
myType = GeomAbs_Ellipse;
Elips = gp_Elips( Axe, Major, Minor);
GeomEllipsePtr = new Geom_Ellipse(Elips) ;
}
else if ( Major > Minor) {
myType = GeomAbs_Ellipse;
Elips = gp_Elips( Axe, Major, Minor);
GeomEllipsePtr = new Geom_Ellipse(Elips);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
myResult = new GeomAdaptor_HCurve(aGACurve);
GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
myResult = new GeomAdaptor_HCurve(aGACurve);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
}
else {
myIsApprox = Standard_True;
myType = GeomAbs_BSplineCurve;
PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
GeomAdaptor_Curve aGACurve(ApproxCurve);
myResult = new GeomAdaptor_HCurve(aGACurve);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
}
}
else {
myIsApprox = Standard_True;
}
}
}
else {
myIsApprox = Standard_True;
// No way to build the canonical curve, approximate as B-spline
if (myIsApprox)
{
myType = GeomAbs_BSplineCurve;
PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
@ -702,10 +753,26 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
myResult = new GeomAdaptor_HCurve(aGACurve);
// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
}
else if (GeomCirclePtr || GeomEllipsePtr)
{
Handle(Geom_Curve) aResultCurve = GeomCirclePtr;
if (aResultCurve.IsNull())
aResultCurve = GeomEllipsePtr;
// start and end parameters of the projected curve
Standard_Real aParFirst = myCurve->FirstParameter();
Standard_Real aParLast = myCurve->LastParameter();
gp_Pnt aPntFirst = ProjectPnt(myPlane, myDirection, myCurve->Value(aParFirst));
gp_Pnt aPntLast = ProjectPnt(myPlane, myDirection, myCurve->Value(aParLast));
GeomLib_Tool::Parameter(aResultCurve, aPntFirst, Precision::Confusion(), myFirstPar);
GeomLib_Tool::Parameter(aResultCurve, aPntLast, Precision::Confusion(), myLastPar);
while (myLastPar <= myFirstPar)
myLastPar += myResult->Period();
}
}
break;
case GeomAbs_Parabola:
{
myKeepParam = Standard_True;
// P(u) = O + (u*u)/(4*f) * Xc + u * Yc
// ==> Q(u) = f(P(u))
// = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)
@ -757,6 +824,7 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
break;
case GeomAbs_Hyperbola:
{
myKeepParam = Standard_True;
// P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
// ==> Q(u) = f(P(u))
// = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)
@ -824,6 +892,7 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
Handle(Geom_BezierCurve) ProjCu =
Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
myKeepParam = Standard_True;
myIsApprox = Standard_False;
myType = Type;
for ( Standard_Integer i = 1; i <= NbPoles; i++) {
@ -847,6 +916,7 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
myKeepParam = Standard_True;
myIsApprox = Standard_False;
myType = Type;
for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
@ -862,6 +932,7 @@ void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
break;
default:
{
myKeepParam = Standard_True;
myIsApprox = Standard_True;
myType = GeomAbs_BSplineCurve;
PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);

View File

@ -3447,6 +3447,30 @@ static Standard_Integer OCC30990 (Draw_Interpretor& theDI, Standard_Integer theN
return 0;
}
//=======================================================================
//function : OCC31294
//purpose : check list of shapes generated from shape, which is not any subshape
// of input shape for prism algorithm
//=======================================================================
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
static Standard_Integer OCC31294(Draw_Interpretor& di, Standard_Integer, const char**)
{
BRepBuilderAPI_MakeVertex mkVert(gp_Pnt(0., 0., 0.));
BRepBuilderAPI_MakeVertex mkDummy(gp_Pnt(0., 0., 0.));
BRepPrimAPI_MakePrism mkPrism(mkVert.Shape(), gp_Vec(0., 0., 1.));
Standard_Integer nbgen = mkPrism.Generated(mkVert.Shape()).Extent();
Standard_Integer nbdummy = mkPrism.Generated(mkDummy.Shape()).Extent();
if (nbgen != 1 || nbdummy != 0)
{
di << "Error: wrong generated list \n";
}
return 0;
}
void QABugs::Commands_20(Draw_Interpretor& theCommands) {
const char *group = "QABugs";
@ -3511,6 +3535,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
theCommands.Add("OCC30704", "OCC30704", __FILE__, OCC30704, group);
theCommands.Add("OCC30704_1", "OCC30704_1", __FILE__, OCC30704_1, group);
theCommands.Add("OCC31294", "OCC31294", __FILE__, OCC31294, group);
return;
}

View File

@ -1315,7 +1315,9 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(T
NonManifoldGroup->Append(aSubShell);
}
}
else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
else if (!isManifold &&
(aSubShape.ShapeType() == TopAbs_SHELL || aSubShape.ShapeType() == TopAbs_FACE))
{
RepItemSeq->Append(aSubShape);
NonManifoldGroup->Append(aSubShape);
}

View File

@ -251,6 +251,11 @@ Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolume
Points3D (anArrayOfPnt);
if (!theMgr.IsOverlapAllowed())
{
if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.Overlaps (anArrayOfPnt, mySensType, aDummy);
}
for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
{
if (!theMgr.Overlaps (anArrayOfPnt->Value(aPntIdx)))

View File

@ -254,6 +254,11 @@ Standard_Boolean Select3D_SensitivePoly::elementIsInside (SelectBasics_Selecting
}
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0), myPolyg.Pnt3d (aSegmentIdx + 1), aDummy);
}
return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0))
&& theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1));
}

View File

@ -31,6 +31,7 @@ Select3D_SensitiveSegment::Select3D_SensitiveSegment (const Handle(SelectMgr_Ent
const gp_Pnt& theLastPnt)
: Select3D_SensitiveEntity (theOwnerId)
{
mySFactor = 3;
myStart = theFirstPnt;
myEnd = theLastPnt;
}
@ -44,6 +45,10 @@ Standard_Boolean Select3D_SensitiveSegment::Matches (SelectBasics_SelectingVolum
{
if (!theMgr.IsOverlapAllowed()) // check for inclusion
{
if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
{
return theMgr.Overlaps (myStart, myEnd, thePickResult);
}
return theMgr.Overlaps (myStart, thePickResult) && theMgr.Overlaps (myEnd, thePickResult);
}

View File

@ -50,6 +50,11 @@ Standard_Boolean Select3D_SensitiveTriangle::Matches (SelectBasics_SelectingVolu
{
if (!theMgr.IsOverlapAllowed())
{
if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.Overlaps (myPoints[0], myPoints[1], myPoints[2], mySensType, aDummy);
}
return theMgr.Overlaps (myPoints[0])
&& theMgr.Overlaps (myPoints[1])
&& theMgr.Overlaps (myPoints[2]);

View File

@ -314,6 +314,11 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
{
const gp_Pnt& aSegmPnt1 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 1));
const gp_Pnt& aSegmPnt2 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 2));
if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.Overlaps (aSegmPnt1, aSegmPnt2, aDummy);
}
return theMgr.Overlaps (aSegmPnt1) && theMgr.Overlaps (aSegmPnt2);
}
else
@ -324,6 +329,11 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
const gp_Pnt& aPnt1 = myTriangul->Nodes().Value (aNode1);
const gp_Pnt& aPnt2 = myTriangul->Nodes().Value (aNode2);
const gp_Pnt& aPnt3 = myTriangul->Nodes().Value (aNode3);
if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, mySensType, aDummy);
}
return theMgr.Overlaps (aPnt1)
&& theMgr.Overlaps (aPnt2)
&& theMgr.Overlaps (aPnt3);

View File

@ -229,6 +229,7 @@ void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1
return;
mySelectingVolumes[FrustumSet]->Build (thePoints);
Handle(SelectMgr_TriangularFrustumSet)::DownCast (mySelectingVolumes[FrustumSet])->SetAllowOverlapDetection (IsOverlapAllowed());
}
//=======================================================================
@ -401,7 +402,7 @@ void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boo
//=======================================================================
Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
{
return myActiveSelectionType != Box || myToAllowOverlap;
return myToAllowOverlap || myActiveSelectionType == Point;
}
//=======================================================================

View File

@ -158,7 +158,6 @@ public:
//! Throws exception if active selection type is not Point.
Standard_EXPORT virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
//! Is used for rectangular selection only
//! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
//! mark both included and overlapped entities as matched
Standard_EXPORT virtual void AllowOverlapDetection (const Standard_Boolean theIsToAllow);

View File

@ -22,6 +22,14 @@
#define MEMORY_BLOCK_SIZE 512 * 7
// =======================================================================
// function : SelectMgr_TriangularFrustumSet
// purpose :
// =======================================================================
SelectMgr_TriangularFrustumSet::SelectMgr_TriangularFrustumSet()
: myToAllowOverlap (Standard_False)
{}
// =======================================================================
// function : BuildSelectingVolume
// purpose : Meshes polygon bounded by polyline. Than organizes a set of
@ -34,14 +42,20 @@ void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoint
myFrustums.Clear();
Handle(NCollection_IncAllocator) anAllocator = new NCollection_IncAllocator (MEMORY_BLOCK_SIZE);
Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun (anAllocator);
Standard_Integer aPtsLower = thePoints.Lower();
Standard_Integer aPtsUpper = thePoints.Upper();
IMeshData::VectorOfInteger anIndexes(aPtsUpper - aPtsLower, anAllocator);
IMeshData::VectorOfInteger anIndexes (thePoints.Size(), anAllocator);
myBoundaryPoints.Resize (aPtsLower, aPtsLower + 2 * (thePoints.Size()) - 1, Standard_False);
for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
{
BRepMesh_Vertex aVertex(thePoints.Value(aPtIdx).XY(), aPtIdx, BRepMesh_Frontier);
anIndexes.Append(aMeshStructure->AddNode(aVertex));
BRepMesh_Vertex aVertex (thePoints.Value (aPtIdx).XY(), aPtIdx, BRepMesh_Frontier);
anIndexes.Append (aMeshStructure->AddNode (aVertex));
const gp_Pnt aNearPnt = myBuilder->ProjectPntOnViewPlane (aVertex.Coord().X(), aVertex.Coord().Y(), 0.0);
const gp_Pnt aFarPnt = myBuilder->ProjectPntOnViewPlane (aVertex.Coord().X(), aVertex.Coord().Y(), 1.0);
myBoundaryPoints.SetValue (aPtIdx, aNearPnt);
myBoundaryPoints.SetValue (aPtIdx + thePoints.Size(), aFarPnt);
}
Standard_Real aPtSum = 0;
@ -118,6 +132,14 @@ Handle(SelectMgr_BaseFrustum) SelectMgr_TriangularFrustumSet::ScaleAndTransform
aRes->myFrustums.Append (Handle(SelectMgr_TriangularFrustum)::DownCast (anIter.Value()->ScaleAndTransform (theScale, theTrsf)));
}
aRes->myBoundaryPoints.Resize (myBoundaryPoints.Lower(), myBoundaryPoints.Upper(), Standard_False);
for (Standard_Integer anIdx = myBoundaryPoints.Lower(); anIdx <= myBoundaryPoints.Upper(); anIdx++)
{
gp_Pnt aPoint = myBoundaryPoints.Value (anIdx);
theTrsf.Transforms (aPoint.ChangeCoord());
aRes->myBoundaryPoints.SetValue (anIdx, aPoint);
}
return aRes;
}
@ -145,12 +167,43 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3&
// =======================================================================
Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3& theMinPnt,
const SelectMgr_Vec3& theMaxPnt,
Standard_Boolean* /*theInside*/) const
Standard_Boolean* theInside) const
{
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
{
if (anIter.Value()->Overlaps (theMinPnt, theMaxPnt, NULL))
return Standard_True;
{
if (myToAllowOverlap || theInside == NULL)
{
return Standard_True;
}
else
{
gp_Pnt aMinMaxPnts[2] = { gp_Pnt (theMinPnt.x(), theMinPnt.y(), theMinPnt.z()),
gp_Pnt (theMaxPnt.x(), theMaxPnt.y(), theMaxPnt.z())};
gp_Pnt anOffset[3] = { gp_Pnt (aMinMaxPnts[1].X() - aMinMaxPnts[0].X(), 0.0, 0.0),
gp_Pnt (0.0, aMinMaxPnts[1].Y() - aMinMaxPnts[0].Y(), 0.0),
gp_Pnt (0.0, 0.0, aMinMaxPnts[1].Z() - aMinMaxPnts[0].Z()) };
Standard_Integer aSign = 1;
for (Standard_Integer aPntsIdx = 0; aPntsIdx < 2; aPntsIdx++)
{
for (Standard_Integer aCoordIdx = 0; aCoordIdx < 3; aCoordIdx++)
{
gp_Pnt anOffsetPnt = aMinMaxPnts [aPntsIdx].XYZ() + aSign * anOffset [aCoordIdx].XYZ();
if (isIntersectBoundary (aMinMaxPnts [aPntsIdx], anOffsetPnt)
|| isIntersectBoundary (anOffsetPnt, anOffsetPnt.XYZ() + aSign * anOffset [(aCoordIdx + 1) % 3].XYZ()))
{
*theInside &= Standard_False;
return Standard_True;
}
}
aSign = -aSign;
}
return Standard_True;
}
}
}
return Standard_False;
@ -185,7 +238,25 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const TColgp_Array1Of
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
{
if (anIter.Value()->Overlaps (theArrayOfPts, theSensType, theClipRange, thePickResult))
return Standard_True;
{
if (myToAllowOverlap)
{
return Standard_True;
}
else
{
Standard_Integer aPtsLower = theArrayOfPts.Lower();
Standard_Integer aPtsUpper = theArrayOfPts.Upper();
for (Standard_Integer anIdx = aPtsLower; anIdx <= aPtsUpper; anIdx++)
{
if (isIntersectBoundary (theArrayOfPts.Value (anIdx), theArrayOfPts.Value (anIdx < aPtsUpper ? anIdx + 1 : aPtsLower)))
{
return Standard_False;
}
}
return Standard_True;
}
}
}
return Standard_False;
@ -203,7 +274,20 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
{
if (anIter.Value()->Overlaps (thePnt1, thePnt2, theClipRange, thePickResult))
return Standard_True;
{
if (myToAllowOverlap)
{
return Standard_True;
}
else
{
if (isIntersectBoundary (thePnt1, thePnt2))
{
return Standard_False;
}
return Standard_True;
}
}
}
return Standard_False;
@ -223,7 +307,22 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
{
if (anIter.Value()->Overlaps (thePnt1, thePnt2, thePnt3, theSensType, theClipRange, thePickResult))
return Standard_True;
{
if (myToAllowOverlap)
{
return Standard_True;
}
else
{
if (isIntersectBoundary (thePnt1, thePnt2)
|| isIntersectBoundary (thePnt2, thePnt3)
|| isIntersectBoundary (thePnt3, thePnt1))
{
return Standard_False;
}
return Standard_True;
}
}
}
return Standard_False;
@ -243,4 +342,83 @@ void SelectMgr_TriangularFrustumSet::GetPlanes (NCollection_Vector<SelectMgr_Vec
}
}
//=======================================================================
// function : SetAllowOverlapDetection
// purpose :
//=======================================================================
void SelectMgr_TriangularFrustumSet::SetAllowOverlapDetection (const Standard_Boolean theIsToAllow)
{
myToAllowOverlap = theIsToAllow;
}
//=======================================================================
// function : isIntersectBoundary
// purpose :
//=======================================================================
Standard_Boolean SelectMgr_TriangularFrustumSet::isIntersectBoundary (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2) const
{
Standard_Integer aFacesNb = myBoundaryPoints.Size() / 2;
gp_Vec aDir = thePnt2.XYZ() - thePnt1.XYZ();
gp_Pnt anOrig = thePnt1;
for (Standard_Integer anIdx = myBoundaryPoints.Lower(); anIdx < aFacesNb + myBoundaryPoints.Lower(); anIdx++)
{
gp_Pnt aFace[4] = { myBoundaryPoints.Value (anIdx),
myBoundaryPoints.Value (anIdx + aFacesNb),
myBoundaryPoints.Value (anIdx % aFacesNb + 1 + aFacesNb),
myBoundaryPoints.Value (anIdx % aFacesNb + 1) };
if (segmentTriangleIntersection (anOrig, aDir, aFace[0], aFace[1], aFace[2])
|| segmentTriangleIntersection (anOrig, aDir, aFace[0], aFace[2], aFace[3]))
{
return Standard_True;
}
}
return Standard_False;
}
//=======================================================================
// function : segmentTriangleIntersection
// purpose : Moller-Trumbore ray-triangle intersection test
//=======================================================================
Standard_Boolean SelectMgr_TriangularFrustumSet::segmentTriangleIntersection (const gp_Pnt& theOrig, const gp_Vec& theDir,
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3) const
{
gp_Vec aPVec, aTVec, aQVec;
Standard_Real aD, aInvD, anU, aV, aT;
gp_Vec anEdge1 = theV2.XYZ() - theV1.XYZ();
gp_Vec anEdge2 = theV3.XYZ() - theV1.XYZ();
aPVec = theDir.Crossed (anEdge2);
aD = anEdge1.Dot (aPVec);
if (fabs (aD) < gp::Resolution())
{
return Standard_False;
}
aInvD = 1.0 / aD;
aTVec = theOrig.XYZ() - theV1.XYZ();
anU = aInvD * aTVec.Dot (aPVec);
if (anU < 0.0 || anU > 1.0)
{
return Standard_False;
}
aQVec = aTVec.Crossed (anEdge1);
aV = aInvD * theDir.Dot (aQVec);
if (aV < 0.0 || anU + aV > 1.0)
{
return Standard_False;
}
aT = aInvD * anEdge2.Dot (aQVec);
if (aT < 0 || aT > 1)
{
return Standard_False;
}
return Standard_True;
}
#undef MEMORY_BLOCK_SIZE

View File

@ -37,7 +37,7 @@ class SelectMgr_TriangularFrustumSet : public SelectMgr_BaseFrustum
{
public:
SelectMgr_TriangularFrustumSet() {};
SelectMgr_TriangularFrustumSet();
~SelectMgr_TriangularFrustumSet() {};
@ -84,9 +84,24 @@ public:
//! Ax + By + Cz + D = 0) to the given vector
Standard_EXPORT virtual void GetPlanes (NCollection_Vector<SelectMgr_Vec4>& thePlaneEquations) const Standard_OVERRIDE;
//! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
//! mark both included and overlapped entities as matched
Standard_EXPORT virtual void SetAllowOverlapDetection (const Standard_Boolean theIsToAllow);
private:
SelectMgr_TriangFrustums myFrustums;
//! Checks whether the segment intersects with the boundary of the current volume selection
Standard_EXPORT Standard_Boolean isIntersectBoundary (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2) const;
//! Checks whether the triangle intersects with a segment
Standard_EXPORT Standard_Boolean segmentTriangleIntersection (const gp_Pnt &theOrig, const gp_Vec& theDir,
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3) const;
private:
SelectMgr_TriangFrustums myFrustums;
TColgp_Array1OfPnt myBoundaryPoints;
Standard_Boolean myToAllowOverlap;
};
#endif // _SelectMgr_TriangularFrustumSet_HeaderFile

View File

@ -86,6 +86,7 @@
#include <Extrema_ExtPS.hxx>
#include <BRepTools.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <ElCLib.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_UnifySameDomain,Standard_Transient)
@ -483,6 +484,7 @@ static Standard_Boolean FindClosestPoints(const TopoDS_Edge& theEdge1,
//purpose : auxilary
//=======================================================================
static void ReconstructMissedSeam(const TopTools_SequenceOfShape& theEdges,
const TopTools_SequenceOfShape& theRemovedEdges,
const TopTools_MapOfShape& theUsedEdges,
const TopoDS_Face& theFrefFace,
const TopoDS_Vertex& theCurVertex,
@ -536,52 +538,125 @@ static void ReconstructMissedSeam(const TopTools_SequenceOfShape& theEdges,
//Build missed seam edge
theLastVertexOfSeam = TopExp::FirstVertex(theNextEdge, Standard_True); //with orientation
Standard_Real CurTol = BRep_Tool::Tolerance(theCurVertex);
Standard_Real LastTol = BRep_Tool::Tolerance(theLastVertexOfSeam);
Standard_Real anU = (CurTol < LastTol)? theCurPoint.X() : theStartOfNextEdge.X();
Handle(Geom_Curve) Uiso = RefSurf->UIso(anU);
TopoDS_Vertex V1, V2;
Standard_Real Param1, Param2;
if (Ydir > 0)
{
V1 = theCurVertex; V2 = theLastVertexOfSeam;
Param1 = theCurPoint.Y(); Param2 = theStartOfNextEdge.Y();
}
else
{
V1 = theLastVertexOfSeam; V2 = theCurVertex;
Param1 = theStartOfNextEdge.Y(); Param2 = theCurPoint.Y();
}
TopoDS_Edge MissedSeam = BRepLib_MakeEdge(Uiso, V1, V2, Param1, Param2);
Standard_Real Vorigin = 0.;
//Correct Param1 and Param2 if needed:
//when Uiso-curve is periodic and Param1 and Param2 do not fit into V-range of surface,
//BRepLib_MakeEdge may shift Param1 and Param2
Standard_Real InitialParam1 = Param1, InitialParam2 = Param2;
Handle(Geom_Curve) MissedCurve = BRep_Tool::Curve(MissedSeam, Param1, Param2);
if ((Param1 != InitialParam1 || Param2 != InitialParam2) &&
MissedCurve->IsPeriodic())
{
//Vorigin = -(MissedCurve->Period());
Vorigin = -(Param1 - InitialParam1);
}
/////////////////////////////////////
Handle(Geom2d_Line) PC1 = new Geom2d_Line(gp_Pnt2d(anU, Vorigin), gp_Dir2d(0., 1.));
gp_Vec2d Offset(theUperiod, 0.);
if (Ydir > 0)
Offset *= -1;
Handle(Geom2d_Curve) PC2 = Handle(Geom2d_Curve)::DownCast(PC1->Copy());
PC2->Translate(Offset);
Standard_Real Param1, Param2, anU = 0.;
Handle(Geom_Curve) Uiso;
BRep_Builder BB;
if (Ydir > 0)
BB.UpdateEdge(MissedSeam, PC1, PC2, theFrefFace, 0.);
TopoDS_Edge aRemovedEdge; //try to find it in <RemovedEdges>
for (Standard_Integer i = 1; i <= theRemovedEdges.Length(); i++)
{
const TopoDS_Edge& anEdge = TopoDS::Edge(theRemovedEdges(i));
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(anEdge, aV1, aV2);
if ((aV1.IsSame(theCurVertex) && aV2.IsSame(theLastVertexOfSeam)) ||
(aV1.IsSame(theLastVertexOfSeam) && aV2.IsSame(theCurVertex)))
{
Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(anEdge, theFrefFace, Param1, Param2);
if (!aPC.IsNull())
{
aRemovedEdge = anEdge;
break;
}
}
}
if (aRemovedEdge.IsNull())
{
Standard_Real CurTol = BRep_Tool::Tolerance(theCurVertex);
Standard_Real LastTol = BRep_Tool::Tolerance(theLastVertexOfSeam);
anU = (CurTol < LastTol)? theCurPoint.X() : theStartOfNextEdge.X();
Uiso = RefSurf->UIso(anU);
if (Ydir > 0)
{
V1 = theCurVertex; V2 = theLastVertexOfSeam;
Param1 = theCurPoint.Y(); Param2 = theStartOfNextEdge.Y();
}
else
{
V1 = theLastVertexOfSeam; V2 = theCurVertex;
Param1 = theStartOfNextEdge.Y(); Param2 = theCurPoint.Y();
}
}
else
BB.UpdateEdge(MissedSeam, PC2, PC1, theFrefFace, 0.);
BB.Continuity(MissedSeam, theFrefFace, theFrefFace, aContinuity);
if (Ydir < 0)
MissedSeam.Reverse();
{
TopExp::Vertices(aRemovedEdge, V1, V2);
Uiso = BRep_Tool::Curve(aRemovedEdge, Param1, Param2);
}
TopoDS_Edge MissedSeam = BRepLib_MakeEdge(Uiso, V1, V2, Param1, Param2);
BRep_Builder BB;
gp_Vec2d Offset(theUperiod, 0.);
if (aRemovedEdge.IsNull())
{
Standard_Real Vorigin = 0.;
//Correct Param1 and Param2 if needed:
//when Uiso-curve is periodic and Param1 and Param2 do not fit into V-range of surface,
//BRepLib_MakeEdge may shift Param1 and Param2
Standard_Real InitialParam1 = Param1, InitialParam2 = Param2;
Handle(Geom_Curve) MissedCurve = BRep_Tool::Curve(MissedSeam, Param1, Param2);
if ((Param1 != InitialParam1 || Param2 != InitialParam2) &&
MissedCurve->IsPeriodic())
{
//Vorigin = -(MissedCurve->Period());
Vorigin = -(Param1 - InitialParam1);
}
/////////////////////////////////////
Handle(Geom2d_Line) PC1 = new Geom2d_Line(gp_Pnt2d(anU, Vorigin), gp_Dir2d(0., 1.));
Handle(Geom2d_Curve) PC2 = Handle(Geom2d_Curve)::DownCast(PC1->Copy());
if (Ydir > 0)
Offset *= -1;
PC2->Translate(Offset);
if (Ydir > 0)
BB.UpdateEdge(MissedSeam, PC1, PC2, theFrefFace, 0.);
else
BB.UpdateEdge(MissedSeam, PC2, PC1, theFrefFace, 0.);
if (Ydir < 0)
MissedSeam.Reverse();
}
else
{
TopoDS_Edge aSeam = aRemovedEdge;
aSeam.Orientation(TopAbs_FORWARD);
Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface(aSeam, theFrefFace, Param1, Param2);
aSeam.Reverse();
Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(aSeam, theFrefFace, Param1, Param2);
Standard_Boolean IsSeam = (PC1 != PC2);
if (!IsSeam) //it was not a seam
{
anU = theCurPoint.X();
gp_Pnt2d PointOnRemovedEdge = PC1->Value(Param1);
Standard_Real Uremovededge = PointOnRemovedEdge.X();
if (Abs(anU - Uremovededge) > theUperiod/2)
{
Standard_Real Sign = (anU > Uremovededge)? 1 : -1;
Offset *= Sign;
PC1 = Handle(Geom2d_Curve)::DownCast(PC2->Copy());
PC1->Translate(Offset);
}
else
{
if (Ydir > 0)
Offset *= -1;
PC2 = Handle(Geom2d_Curve)::DownCast(PC1->Copy());
PC2->Translate(Offset);
}
}
if (theCurVertex.IsSame(V1))
BB.UpdateEdge(MissedSeam, PC1, PC2, theFrefFace, 0.);
else
{
if (IsSeam)
BB.UpdateEdge(MissedSeam, PC1, PC2, theFrefFace, 0.);
else
BB.UpdateEdge(MissedSeam, PC2, PC1, theFrefFace, 0.);
MissedSeam.Reverse();
}
}
BB.Continuity(MissedSeam, theFrefFace, theFrefFace, aContinuity);
BB.Add(theNewWire, MissedSeam);
//add newly created edge into VEmap
MissedSeam.Reverse();
@ -601,129 +676,79 @@ static void TransformPCurves(const TopoDS_Face& theRefFace,
const TopoDS_Face& theFace,
TopTools_MapOfShape& theMapEdgesWithTemporaryPCurves)
{
BRepAdaptor_Surface BAsurf(theFace, Standard_False);
Standard_Real Uperiod = 0., Vperiod = 0.;
Handle(Geom_Surface) RefSurf = BRep_Tool::Surface(theRefFace);
if (RefSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
RefSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf))->BasisSurface();
if (RefSurf->IsUPeriodic())
Uperiod = RefSurf->UPeriod();
if (RefSurf->IsVPeriodic())
Vperiod = RefSurf->VPeriod();
GeomAdaptor_Surface RefGAsurf(RefSurf);
Handle(Geom_Surface) SurfFace = BRep_Tool::Surface(theFace);
if (SurfFace->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
SurfFace = (Handle(Geom_RectangularTrimmedSurface)::DownCast(SurfFace))->BasisSurface();
Standard_Real Ufirst = BAsurf.FirstUParameter(),
Ulast = BAsurf.LastUParameter(),
Vfirst = BAsurf.FirstVParameter(),
Vlast = BAsurf.LastVParameter();
Standard_Real u_mid = (Ufirst + Ulast)/2, v_mid = (Vfirst + Vlast)/2;
gp_Pnt MidPoint = BAsurf.Value(u_mid, v_mid);
Extrema_ExtPS ProjPS(MidPoint, RefGAsurf,
Precision::PConfusion(), Precision::PConfusion());
Standard_Integer indmin = 1;
for (Standard_Integer iext = 2; iext <= ProjPS.NbExt(); iext++)
if (ProjPS.SquareDistance(iext) < ProjPS.SquareDistance(indmin))
indmin = iext;
Standard_Boolean ToModify = Standard_False,
ToTranslate = Standard_False, Y_Reverse = Standard_False;
Standard_Real uu, vv;
ProjPS.Point(indmin).Parameter(uu,vv);
//Check uu and vv
if (Abs(u_mid + Uperiod - uu) <= Precision::PConfusion())
uu = u_mid;
if (Abs(u_mid - uu) <= Precision::PConfusion())
uu = u_mid;
if (Abs(v_mid + Vperiod - vv) <= Precision::PConfusion())
vv = v_mid;
if (Abs(v_mid - vv) <= Precision::PConfusion())
vv = v_mid;
gp_Vec2d Translation(uu - u_mid, vv - v_mid);
gp_Vec2d Translation(0.,0.);
Standard_Boolean X_Reverse = Standard_False, Y_Reverse = Standard_False;
Standard_Real u_dx, v_dx, u_dy, v_dy;
//Get axes of surface of face and of surface of RefFace
Handle(Geom_ElementarySurface) ElemSurfFace = Handle(Geom_ElementarySurface)::DownCast(SurfFace);
Handle(Geom_ElementarySurface) ElemRefSurf = Handle(Geom_ElementarySurface)::DownCast(RefSurf);
Standard_Real Delta = (Precision::IsInfinite(Ufirst) || Precision::IsInfinite(Ulast))?
1. : (Ulast - Ufirst)/4;
Standard_Real Offset = (Uperiod == 0.)? Delta : Min(Uperiod/8, Delta);
Standard_Real u1 = u_mid + Offset, v1 = v_mid;
gp_Pnt DX = BAsurf.Value(u1, v1);
ProjPS.Perform(DX);
indmin = 1;
for (Standard_Integer iext = 2; iext <= ProjPS.NbExt(); iext++)
if (ProjPS.SquareDistance(iext) < ProjPS.SquareDistance(indmin))
indmin = iext;
ProjPS.Point(indmin).Parameter(u_dx, v_dx);
if (Uperiod != 0. &&
Abs(uu - u_dx) > Uperiod/2)
if (!ElemSurfFace.IsNull() && !ElemRefSurf.IsNull())
{
if (uu < Uperiod/2 &&
u_dx > Uperiod/2)
X_Reverse = Standard_True;
}
else if (u_dx < uu)
X_Reverse = Standard_True;
Delta = (Precision::IsInfinite(Vfirst) || Precision::IsInfinite(Vlast))?
1. : (Vlast - Vfirst)/4;
Offset = (Vperiod == 0.)? Delta : Min(Vperiod/8, Delta);
Standard_Real u2 = u_mid, v2 = v_mid + Offset;
gp_Pnt DY = BAsurf.Value(u2, v2);
ProjPS.Perform(DY);
indmin = 1;
for (Standard_Integer iext = 2; iext <= ProjPS.NbExt(); iext++)
if (ProjPS.SquareDistance(iext) < ProjPS.SquareDistance(indmin))
indmin = iext;
gp_Ax3 AxisOfSurfFace = ElemSurfFace->Position();
gp_Ax3 AxisOfRefSurf = ElemRefSurf->Position();
ProjPS.Point(indmin).Parameter(u_dy, v_dy);
if (Vperiod != 0. &&
Abs(vv - v_dy) > Vperiod/2)
{
if (vv < Vperiod/2 &&
v_dy > Vperiod/2)
gp_Pnt OriginRefSurf = AxisOfRefSurf.Location();
Standard_Real aParam = ElCLib::LineParameter(AxisOfSurfFace.Axis(), OriginRefSurf);
if (Abs(aParam) > Precision::PConfusion())
Translation.SetY(-aParam);
gp_Dir VdirSurfFace = AxisOfSurfFace.Direction();
gp_Dir VdirRefSurf = AxisOfRefSurf.Direction();
gp_Dir XdirSurfFace = AxisOfSurfFace.XDirection();
gp_Dir XdirRefSurf = AxisOfRefSurf.XDirection();
Standard_Real anAngle = XdirRefSurf.AngleWithRef(XdirSurfFace, VdirRefSurf);
if (!AxisOfRefSurf.Direct())
anAngle *= -1;
if (Abs(anAngle) > Precision::PConfusion())
Translation.SetX(anAngle);
Standard_Real ScalProd = VdirSurfFace * VdirRefSurf;
if (ScalProd < 0.)
Y_Reverse = Standard_True;
}
else if (v_dy < vv)
Y_Reverse = Standard_True;
gp_Trsf2d aTrsf;
if (X_Reverse && Y_Reverse)
aTrsf.SetMirror(gp::Origin2d());
else if (X_Reverse)
aTrsf.SetMirror(gp::OY2d());
else if (Y_Reverse)
aTrsf.SetMirror(gp::OX2d());
aTrsf.SetTranslationPart(Translation);
ToTranslate = !(Translation.XY().IsEqual(gp_XY(0.,0.), Precision::PConfusion()));
ToModify = ToTranslate || Y_Reverse;
}
BRep_Builder BB;
TopExp_Explorer Explo(theFace, TopAbs_EDGE);
for (; Explo.More(); Explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
if (BRep_Tool::Degenerated(anEdge) &&
aTrsf.Form() != gp_Identity)
if (BRep_Tool::Degenerated(anEdge) && ToModify)
continue;
if (BRepTools::IsReallyClosed(anEdge, theFace))
continue;
Standard_Real fpar, lpar;
Handle(Geom2d_Curve) PCurveOnRef = BRep_Tool::CurveOnSurface(anEdge, theRefFace, fpar, lpar);
if (!PCurveOnRef.IsNull())
if (!PCurveOnRef.IsNull() && !ToModify)
continue;
Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
Handle(Geom2d_Curve) aNewPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
if (aTrsf.Form() != gp_Identity)
aNewPCurve->Transform(aTrsf);
if (ToTranslate)
aNewPCurve->Translate(Translation);
if (Y_Reverse)
aNewPCurve->Mirror(gp::OX2d());
Standard_Real tmp_first, tmp_last;
Handle(Geom2d_Curve) aPCurveOnRefFace = BRep_Tool::CurveOnSurface(anEdge, theRefFace,
tmp_first, tmp_last);
if (aPCurveOnRefFace.IsNull())
theMapEdgesWithTemporaryPCurves.Add(anEdge);
theMapEdgesWithTemporaryPCurves.Add(anEdge);
BB.UpdateEdge(anEdge, aNewPCurve, theRefFace, 0.);
BB.Range(anEdge, fpar, lpar);
@ -746,7 +771,8 @@ static void AddPCurves(const TopTools_SequenceOfShape& theFaces,
for (Standard_Integer i = 1; i <= theFaces.Length(); i++)
{
const TopoDS_Face& aFace = TopoDS::Face(theFaces(i));
TopoDS_Face aFace = TopoDS::Face(theFaces(i));
aFace.Orientation(TopAbs_FORWARD);
if (aFace.IsSame(theRefFace))
continue;
@ -763,7 +789,8 @@ static void AddPCurves(const TopTools_SequenceOfShape& theFaces,
// Returns true if one of original edges dropped
static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges,
const TopoDS_Shape aShape,
Standard_Integer& anIndex)
Standard_Integer& anIndex,
TopTools_SequenceOfShape& theRemovedEdges)
{
//map of edges
TopTools_IndexedMapOfShape aNewEdges;
@ -771,7 +798,10 @@ static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges,
for(TopExp_Explorer exp(aShape,TopAbs_EDGE); exp.More(); exp.Next()) {
TopoDS_Shape edge = exp.Current();
if(aNewEdges.Contains(edge))
{
aNewEdges.RemoveKey(edge);
theRemovedEdges.Append(edge);
}
else
aNewEdges.Add(edge);
}
@ -785,6 +815,7 @@ static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges,
aNewEdges.RemoveKey(current);
edges.Remove(i);
theRemovedEdges.Append(current);
i--;
if(!isDropped) {
@ -1267,12 +1298,12 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain,
if(c3d1.IsNull() || c3d2.IsNull())
return Standard_False;
while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
if (c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) tc =
Handle(Geom_TrimmedCurve)::DownCast(c3d1);
c3d1 = tc->BasisCurve();
}
while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
if (c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) tc =
Handle(Geom_TrimmedCurve)::DownCast(c3d2);
c3d2 = tc->BasisCurve();
@ -1339,7 +1370,7 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain,
TopoDS_Edge FE = TopoDS::Edge(theChain.First());
Handle(Geom_Curve) c3d = BRep_Tool::Curve(FE,f,l);
while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
if (c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) tc =
Handle(Geom_TrimmedCurve)::DownCast(c3d);
c3d = tc->BasisCurve();
@ -1384,7 +1415,12 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain,
B.Add(E,V[1]);
}
}
else {
else //open chain
{
Standard_Real ParamFirst = BRep_Tool::Parameter(V[0], FE);
TopoDS_Vertex VertexLastOnFE = sae.LastVertex(FE);
Standard_Real ParamLast = BRep_Tool::Parameter(VertexLastOnFE, FE);
if (isSafeInputMode) {
for (int k = 0; k < 2; k++) {
if (!theContext->IsRecorded(V[k])) {
@ -1396,37 +1432,29 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain,
V[k] = TopoDS::Vertex(theContext->Apply(V[k]));
}
}
gp_Pnt PV1 = BRep_Tool::Pnt(V[0]);
gp_Pnt PV2 = BRep_Tool::Pnt(V[1]);
TopoDS_Vertex VM = sae.LastVertex(FE);
gp_Pnt PVM = BRep_Tool::Pnt(VM);
GC_MakeCircle MC (PV1,PVM,PV2);
Handle(Geom_Circle) C = MC.Value();
gp_Pnt P0 = C->Location();
gp_Dir D1(gp_Vec(P0,PV1));
gp_Dir D2(gp_Vec(P0,PV2));
Standard_Real fpar = C->XAxis().Direction().Angle(D1);
if(fabs(fpar)>Precision::Confusion()) {
// check orientation
gp_Dir ND = C->XAxis().Direction().Crossed(D1);
if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
fpar = -fpar;
}
}
Standard_Real lpar = C->XAxis().Direction().Angle(D2);
if(fabs(lpar)>Precision::Confusion()) {
// check orientation
gp_Dir ND = C->XAxis().Direction().Crossed(D2);
if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
lpar = -lpar;
}
}
if (lpar < fpar) lpar += 2*M_PI;
Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar);
gp_Pnt PointFirst = BRep_Tool::Pnt(V[0]);
while (Abs(ParamLast - ParamFirst) > 7*M_PI/8)
ParamLast = (ParamFirst + ParamLast)/2;
BRepAdaptor_Curve BAcurveFE(FE);
gp_Pnt PointLast = BAcurveFE.Value(ParamLast);
gp_Pnt Origin = Cir->Circ().Location();
gp_Dir Dir1 = gp_Vec(Origin, PointFirst);
gp_Dir Dir2 = gp_Vec(Origin, PointLast);
gp_Dir Vdir = Dir1 ^ Dir2;
gp_Ax2 anAx2(Origin, Vdir, Dir1);
Handle(Geom_Circle) aNewCircle = new Geom_Circle(anAx2, Cir->Radius());
gp_Pnt PointLastInChain = BRep_Tool::Pnt(V[1]);
gp_Dir DirLastInChain = gp_Vec(Origin, PointLastInChain);
Standard_Real lpar = Dir1.AngleWithRef(DirLastInChain, Vdir);
if (lpar < 0.)
lpar += 2*M_PI;
Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(aNewCircle,0.,lpar);
B.MakeEdge (E,tc,Precision::Confusion());
B.Add(E,V[0]);
B.Add(E,V[1]);
B.UpdateVertex(V[0], fpar, E, 0.);
B.UpdateVertex(V[0], 0., E, 0.);
B.UpdateVertex(V[1], lpar, E, 0.);
}
OutEdge = E;
@ -1445,7 +1473,7 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain,
TopLoc_Location Loc;
Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1);
if(c3d.IsNull()) continue;
while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
if (c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) tc =
Handle(Geom_TrimmedCurve)::DownCast(c3d);
c3d = tc->BasisCurve();
@ -2009,9 +2037,10 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
// Boundary edges for the new face
TopTools_SequenceOfShape edges;
TopTools_SequenceOfShape RemovedEdges;
Standard_Integer dummy;
AddOrdinaryEdges(edges, aFace, dummy);
AddOrdinaryEdges(edges, aFace, dummy, RemovedEdges);
// Faces to get unified with the current faces
TopTools_SequenceOfShape faces;
@ -2095,7 +2124,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
//
if (IsSameDomain(aFace,aCheckedFace, myLinTol, myAngTol)) {
if (AddOrdinaryEdges(edges,aCheckedFace,dummy)) {
if (AddOrdinaryEdges(edges, aCheckedFace, dummy, RemovedEdges)) {
// sequence edges is modified
i = dummy;
}
@ -2109,7 +2138,9 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
if (faces.Length() > 1) {
//Add correct pcurves for the reference surface to the edges of other faces
AddPCurves(faces, RefFace, MapEdgesWithTemporaryPCurves);
TopoDS_Face F_RefFace = RefFace;
F_RefFace.Orientation(TopAbs_FORWARD);
AddPCurves(faces, F_RefFace, MapEdgesWithTemporaryPCurves);
// fill in the connectivity map for selected faces
TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
@ -2159,7 +2190,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
}
}
if (!hasConnectAnotherFaces) {
AddOrdinaryEdges(edges, faces(i), dummy);
AddOrdinaryEdges(edges, faces(i), dummy, RemovedEdges);
faces.Remove(i);
i--;
}
@ -2182,7 +2213,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
for (i = 1; i <= faces.Length(); i++) {
if (faces(i).IsEqual(aLF.First()) ||
faces(i).IsEqual(aLF.Last())) {
AddOrdinaryEdges(edges, faces(i), dummy);
AddOrdinaryEdges(edges, faces(i), dummy, RemovedEdges);
faces.Remove(i);
i--;
}
@ -2443,7 +2474,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
//<edges> do not contain seams => we must reconstruct the seam up to <NextEdge>
gp_Pnt2d StartOfNextEdge;
TopoDS_Vertex LastVertexOfSeam;
ReconstructMissedSeam(edges, UsedEdges, F_RefFace, CurVertex,
ReconstructMissedSeam(edges, RemovedEdges, UsedEdges, F_RefFace, CurVertex,
CurPoint, Uperiod, FaceUmin, CoordTol,
NextEdge, aNewWire, NextPoint,
StartOfNextEdge, LastVertexOfSeam, VEmap);
@ -2527,7 +2558,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
//<edges> do not contain seams => we must reconstruct the seam up to <NextEdge>
gp_Pnt2d StartOfNextEdge;
TopoDS_Vertex LastVertexOfSeam;
ReconstructMissedSeam(edges, UsedEdges, F_RefFace, CurVertex,
ReconstructMissedSeam(edges, RemovedEdges, UsedEdges, F_RefFace, CurVertex,
CurPoint, Uperiod, FaceUmin, CoordTol,
NextEdge, aNewWire, NextPoint,
StartOfNextEdge, LastVertexOfSeam, VEmap);

View File

@ -27,6 +27,7 @@
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <Precision.hxx>
class ShapeBuild_ReShape;
class TopoDS_Shape;

View File

@ -43,6 +43,7 @@
//! - "beta..." or "rc..." for beta releases or release candidates
//! - "project..." for version containing project-specific fixes
//#define OCC_VERSION_DEVELOPMENT "beta"
#define OCC_VERSION_SERVICEPACK 2
// Derived (manually): version as real and string (major.minor)
#define OCC_VERSION 7.4

View File

@ -16,6 +16,7 @@
#include <StdPrs_Isolines.hxx>
#include <Adaptor3d_IsoCurve.hxx>
#include <Bnd_Range.hxx>
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <GCPnts_AbscissaPoint.hxx>
@ -479,6 +480,24 @@ void StdPrs_Isolines::addOnSurface (const Handle(BRepAdaptor_HSurface)& theSurfa
}
}
// re-calculate UV-range basing on p-curves tessellation
Bnd_Range aTrimU, aTrimV;
for (Standard_Integer anI = 1; anI <= aTrimPoints.Length(); ++anI)
{
const gp_Pnt2d& aTrimPnt = aTrimPoints.Value (anI);
aTrimU.Add (aTrimPnt.X());
aTrimV.Add (aTrimPnt.Y());
}
// ignore p-curves tessellation under sampler deflection - it might clamp range
if (!aTrimU.IsVoid() && aTrimU.Delta() <= aSamplerDeflection)
{
aTrimU.SetVoid();
}
if (!aTrimV.IsVoid() && aTrimV.Delta() <= aSamplerDeflection)
{
aTrimV.SetVoid();
}
// Compute a hatching tolerance.
aHatchingTolerance *= 0.1;
aHatchingTolerance = Max (Precision::Confusion(), aHatchingTolerance);
@ -489,11 +508,21 @@ void StdPrs_Isolines::addOnSurface (const Handle(BRepAdaptor_HSurface)& theSurfa
for (Standard_Integer anIso = 1; anIso <= theUIsoParams.Length(); ++anIso)
{
aHatcher.AddXLine (theUIsoParams.Value (anIso));
const Standard_Real anIsoParamU = theUIsoParams.Value (anIso);
if (aTrimU.IsVoid()
|| !aTrimU.IsOut (anIsoParamU))
{
aHatcher.AddXLine (anIsoParamU);
}
}
for (Standard_Integer anIso = 1; anIso <= theVIsoParams.Length(); ++anIso)
{
aHatcher.AddYLine (theVIsoParams.Value (anIso));
const Standard_Real anIsoParamV = theVIsoParams.Value (anIso);
if (aTrimV.IsVoid()
|| !aTrimV.IsOut (anIsoParamV))
{
aHatcher.AddYLine (anIsoParamV);
}
}
// Trim hatching region.

View File

@ -542,9 +542,6 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
return;
}
// add wireframe presentation for isolated edges and vertices
wireframeFromShape (thePrs, theShape, theDrawer);
// Use automatic re-triangulation with deflection-check logic only if this feature is enable
if (theDrawer->IsAutoTriangulation())
{
@ -552,6 +549,9 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
StdPrs_ToolTriangulatedShape::Tessellate (theShape, theDrawer);
}
// add wireframe presentation for isolated edges and vertices
wireframeFromShape (thePrs, theShape, theDrawer);
// add special wireframe presentation for faces without triangulation
wireframeNoTriangFacesFromShape (thePrs, theShape, theDrawer);

View File

@ -39,6 +39,15 @@ StdPrs_ToolRFace::StdPrs_ToolRFace (const Handle(BRepAdaptor_HSurface)& theSurfa
myFace.Orientation(TopAbs_FORWARD);
}
//=======================================================================
//function : Edge
//purpose :
//=======================================================================
const TopoDS_Edge& StdPrs_ToolRFace::Edge() const
{
return TopoDS::Edge (myExplorer.Current());
}
//=======================================================================
//function : next
//purpose :

View File

@ -26,6 +26,7 @@
#include <Geom2dAdaptor_Curve.hxx>
#include <TopAbs_Orientation.hxx>
class BRepAdaptor_HSurface;
class TopoDS_Edge;
//! Iterator over 2D curves restricting a face (skipping internal/external edges).
//! In addition, the algorithm skips NULL curves - IsInvalidGeometry() can be checked if this should be handled within algorithm.
@ -64,6 +65,9 @@ public:
//! Return current curve.
const Adaptor2d_Curve2d& Value() const { return myCurve; }
//! Return current edge.
Standard_EXPORT const TopoDS_Edge& Edge() const;
//! Return current edge orientation.
TopAbs_Orientation Orientation() const { return myExplorer.Current().Orientation(); }

View File

@ -240,7 +240,7 @@ void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace,
Standard_Boolean StdPrs_ToolTriangulatedShape::IsTessellated (const TopoDS_Shape& theShape,
const Handle(Prs3d_Drawer)& theDrawer)
{
return BRepTools::Triangulation (theShape, Prs3d::GetDeflection (theShape, theDrawer));
return BRepTools::Triangulation (theShape, Prs3d::GetDeflection (theShape, theDrawer), true);
}
// =======================================================================

View File

@ -100,6 +100,11 @@ void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation,
return;
}
if (theDrawer->IsAutoTriangulation())
{
StdPrs_ToolTriangulatedShape::Tessellate (theShape, theDrawer);
}
// draw triangulation-only edges
if (Handle(Graphic3d_ArrayOfPrimitives) aTriFreeEdges = AddEdgesOnTriangulation (theShape, Standard_True))
{

View File

@ -113,8 +113,8 @@ void StdSelect_BRepSelectionTool::Load (const Handle(SelectMgr_Selection)& theSe
const Standard_Real theMaxParam)
{
Standard_Integer aPriority = (thePriority == -1) ? GetStandardPriority (theShape, theType) : thePriority;
if( isAutoTriangulation && !BRepTools::Triangulation (theShape, Precision::Infinite()) )
if (isAutoTriangulation
&& !BRepTools::Triangulation (theShape, Precision::Infinite(), true))
{
BRepMesh_IncrementalMesh aMesher(theShape, theDeflection, Standard_False, theDeviationAngle);
}
@ -448,7 +448,15 @@ void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape
if (!aPoints.IsNull()
&& !aPoints->IsEmpty())
{
theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints);
if (aPoints->Length() == 2)
{
// don't waste memory, create a segment
theSensitive = new Select3D_SensitiveSegment (theOwner, aPoints->First(), aPoints->Last());
}
else
{
theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints);
}
return;
}

View File

@ -7575,12 +7575,7 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
return 1;
}
}
if (toAllowOverlap
&& aPnts.Length() != 2)
{
std::cout << "Syntax error: -allowoverlap key is applied only for rectangle selection\n";
return 1;
}
if (toAllowOverlap)
{
aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
@ -13933,10 +13928,10 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"- 1) single click selection\n"
"- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
"- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
"- 4) -allowoverlap manages overlap and inclusion detection in rectangular selection.\n"
" If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined rectangle will be detected,\n"
" otherwise algorithm will chose only fully included sensitives. Default behavior is to detect only full inclusion. "
" (partial inclusion - overlap - is not allowed by default)\n"
"- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
" If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
" rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
" Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
"- 5) any of these selections with shift button pressed",
__FILE__, VSelect, group);
theCommands.Add ("vmoveto",

View File

@ -16,6 +16,7 @@
#include <Interface_CheckIterator.hxx>
#include <Interface_InterfaceModel.hxx>
#include <Interface_Macros.hxx>
#include <Interface_Static.hxx>
#include <Message_Messenger.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
@ -29,6 +30,7 @@
#include <XSControl_Controller.hxx>
#include <XSControl_TransferWriter.hxx>
#include <XSControl_Utils.hxx>
#include <ShapeUpgrade_RemoveLocations.hxx>
IMPLEMENT_STANDARD_RTTIEXT(XSControl_TransferWriter,Standard_Transient)
@ -133,12 +135,22 @@ Standard_Boolean XSControl_TransferWriter::RecognizeShape (const TopoDS_Shape& s
//=======================================================================
IFSelect_ReturnStatus XSControl_TransferWriter::TransferWriteShape
(const Handle(Interface_InterfaceModel)& model,
const TopoDS_Shape& shape)
(const Handle(Interface_InterfaceModel)& theModel,
const TopoDS_Shape& theShape)
{
IFSelect_ReturnStatus status = IFSelect_RetVoid;
if (myController.IsNull()) return IFSelect_RetError;
if (model.IsNull()) return IFSelect_RetVoid;
if (theModel.IsNull()) return IFSelect_RetVoid;
TopoDS_Shape aShape = theShape;
Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
if (isNMMode)
{
ShapeUpgrade_RemoveLocations aRemLoc;
aRemLoc.SetRemoveLevel(TopAbs_COMPOUND);
aRemLoc.Remove(aShape);
aShape = aRemLoc.GetResult();
}
if (myTransferWriter.IsNull()) myTransferWriter = new Transfer_FinderProcess;
// effacer l actor : Controller s en charge
@ -149,10 +161,10 @@ IFSelect_ReturnStatus XSControl_TransferWriter::TransferWriteShape
try {
OCC_CATCH_SIGNALS
PrintStats(myTransferMode);
sout << "****** Transferring Shape, ShapeType = " << shape.ShapeType();
sout << "****** Transferring Shape, ShapeType = " << aShape.ShapeType();
sout<<" ******"<<Message_EndLine;
status = myController->TransferWriteShape
(shape,myTransferWriter,model,myTransferMode);
(aShape,myTransferWriter,theModel,myTransferMode);
}
catch(Standard_Failure const& anException) {
sout<<"**** **** TransferWriteShape, EXCEPTION : ";

4
tests/bugs/filling/begin Normal file
View File

@ -0,0 +1,4 @@
set subgroup filling

View File

View File

View File

View File

View File

View File

View File

@ -0,0 +1,58 @@
puts "============================================================================================="
puts "OCC31464: BRepOffsetAPI_MakeFilling algorithm increases tolerances of vertices in input edges"
puts "============================================================================================="
puts ""
brestore [locate_data_file bug31464.brep] a
set tol [checkmaxtol a]
explode a f
explode a_1 e
filling result 3 0 1 a_1_1 0 a_1_2 0 a_1_4 0 0.0785398166 0.0196349541 a_1 1
savehistory hh
set tol2 [checkmaxtol a]
if { ${tol} != ${tol2}} {
puts "Error: tolerance of input shape changed"
}
generated e2 hh a_1_2
explode a_1_3
generated vv hh a_1_3_1
distmini distvv a_1_3_1 vv
if {[dval distvv_val] > 0.} {
puts "Error: generated vertex is wrong"
}
mkcurve oldc a_1_2
mkcurve newc e2
set log [xdistcc oldc newc -3.92699082e-14 0.0392699082 10]
regexp {Max Distance = +([-0-9.+eE]+)} ${log} full dist
if { [dval dist] != 0. } {
puts "Error: generated edge is wrong"
}
smallview
donly result e2 vv
fit
checkshape result
checknbshapes result -face 1 -wire 1 -edge 3 -vertex 3
set tolres [checkmaxtol result]
if { ${tolres} > 0.0007} {
puts "Error: bad tolerance of result"
}
checkprops result -s 0.00190371
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,29 @@
puts "=========================================================================="
puts "OCC31558: BRepOffsetAPI_MakeFilling algorithm makes turned inside out face"
puts "=========================================================================="
puts ""
brestore [locate_data_file bug31558.brep] a
explode a e
filling result 1 0 9 a_2 0 3.5000410449283663 0.62831853071795896 a 1 3.5000410449283663 1.2566370614359179 a 1 3.5000410449283663 1.8849555921538768 a 1 3.5000410449283663 2.5132741228718358 a 1 3.5000410449283663 3.1415926535897949 a 1 3.5000410449283663 3.7699111843077535 a 1 3.5000410449283663 4.3982297150257130 a 1 3.5000410449283663 5.0265482457436717 a 1 3.5000410449283663 5.6548667764616303 a 1
checkshape result
checknbshapes result -face 1 -wire 1 -edge 1 -vertex 1
set tolres [checkmaxtol result]
if { ${tolres} > 2.e-5} {
puts "Error: bad tolerance of result"
}
checkprops result -s 153.938
smallview
isos result 10
donly result
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@ -20,3 +20,4 @@
020 stlvrml
021 splitshape
022 splitshape_1
023 filling

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