1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

18 Commits

Author SHA1 Message Date
rnv
5457eade20 0032424: [Regression] Mesh - Slow triangulation of a simple shape. 2021-07-22 13:33:11 +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
78 changed files with 1698 additions and 636 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

@@ -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

@@ -97,12 +97,12 @@ 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 = 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 = 20;
if (!mycut)
{
@@ -178,10 +178,12 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
Standard_Boolean aStopCutting = Standard_False;
if (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 ))

View File

@@ -305,23 +305,19 @@ 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;
}
}
else if (aDim1 > aDim2) {
if (myOperation == BOPAlgo_FUSE ||
myOperation == BOPAlgo_CUT) {
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);
@@ -331,6 +327,7 @@ void BOPAlgo_ArgumentAnalyzer::TestTypes()
}
}
}
}
//=======================================================================
//function : TestSelfInterferences
//purpose :

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) {
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(aS, aType, aMS);
TopExp::MapShapes (aSS, 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,13 +141,18 @@ 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);
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(aS, aType);
for (; aExp.More(); aExp.Next()) {
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) {
@@ -179,6 +184,7 @@ void BOPAlgo_CellsBuilder::IndexParts()
}
} // 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

@@ -90,27 +90,62 @@ class BOPAlgo_EdgeEdge :
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);
@@ -1022,6 +1062,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;
@@ -874,8 +911,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;
@@ -940,6 +981,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,13 +325,15 @@ 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 (!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)) {
aBB.Add(aShell, 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

@@ -166,6 +166,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 +179,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) {
@@ -304,6 +310,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();
@@ -366,7 +373,7 @@ void Path (const GeomAdaptor_Surface& aGAS,
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;
@@ -501,8 +508,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 +536,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 +558,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;
}

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);
TopAbs_ShapeEnum aType = theS.ShapeType();
if (aType != TopAbs_COMPOUND)
{
if (!theMFence || theMFence->Add (theS))
{
theLS.Append (theS);
}
else {
theLSX.Append(aS);
return;
}
for (TopoDS_Iterator it (theS); it.More(); it.Next())
{
TreatCompound (it.Value(), theLS, theMFence);
}
}
}
//
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)
}

View File

@@ -286,13 +286,6 @@ void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer,
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

@@ -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();
}
// 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

@@ -34,7 +34,9 @@ public:
//! Constructor.
BRepMesh_DelaunayDeflectionControlMeshAlgo()
: myMaxSqDeflection(-1.),
myIsAllDegenerated(Standard_False)
mySqMinSize(-1.),
myIsAllDegenerated(Standard_False),
myCircles(NULL)
{
}
@@ -65,6 +67,7 @@ protected:
Handle(NCollection_IncAllocator) aTmpAlloc =
new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
mySqMinSize = this->getParameters().MinSize * this->getParameters().MinSize;
myCouplesMap = new IMeshData::MapOfOrientedEdges(3 * this->getStructure()->ElementsOfDomain().Extent(), aTmpAlloc);
myControlNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
myCircles = &theMesher.Circles();
@@ -317,6 +320,10 @@ private:
if (!usePoint (aMidPnt2d, LineDeviation (theNodesInfo[i].Point,
theNodesInfo[j].Point)))
{
if (!rejectSplitLinksForMinSize (theNodesInfo[i],
theNodesInfo[j],
aMidPnt2d))
{
if (!checkLinkEndsForAngularDeviation (theNodesInfo[i],
theNodesInfo[j],
@@ -328,6 +335,18 @@ private:
}
}
}
}
//! Checks that two links produced as the result of a split of
//! the given link by the middle point fit MinSize requirement.
Standard_Boolean rejectSplitLinksForMinSize (const TriangleNodeInfo& theNodeInfo1,
const TriangleNodeInfo& theNodeInfo2,
const gp_XY& theMidPoint)
{
const gp_Pnt aPnt = getPoint3d (theMidPoint);
return ((theNodeInfo1.Point - aPnt.XYZ()).SquareModulus() < mySqMinSize ||
(theNodeInfo2.Point - aPnt.XYZ()).SquareModulus() < mySqMinSize);
}
//! Checks the given point (located between the given nodes)
//! for specified angular deviation.
@@ -344,8 +363,10 @@ private:
{
Standard_Real anAngle = aNorm1.Angle(aNorm2);
if (anAngle > this->getParameters().AngleInterior)
{
return Standard_False;
}
}
#if 0
else if (GeomLib::NormEstim(aSurf, theMidPoint, Precision::Confusion(), aNorm1) != 0)
{
@@ -360,6 +381,14 @@ private:
return Standard_True;
}
//! Returns 3d point corresponding to the given one in 2d space.
gp_Pnt getPoint3d (const gp_XY& thePnt2d)
{
gp_Pnt aPnt;
this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
return aPnt;
}
//! Computes deflection of the given point and caches it for
//! insertion in case if it overflows deflection.
//! @return True if point has been cached for insertion.
@@ -368,8 +397,7 @@ private:
const gp_XY& thePnt2d,
const DeflectionFunctor& theDeflectionFunctor)
{
gp_Pnt aPnt;
this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
const gp_Pnt aPnt = getPoint3d (thePnt2d);
if (!checkDeflectionOfPointAndUpdateCache(thePnt2d, aPnt, theDeflectionFunctor.SquareDeviation(aPnt)))
{
myControlNodes->Append(thePnt2d);
@@ -401,14 +429,14 @@ private:
return rejectByMinSize(thePnt2d, thePnt3d);
}
//! Checks the given node for
//! Checks distance between the given node and nodes of triangles
//! shot by it for MinSize criteria.
//! This check is expected to roughly estimate and prevent
//! generation of triangles with sides smaller than MinSize.
Standard_Boolean rejectByMinSize(
const gp_XY& thePnt2d,
const gp_Pnt& thePnt3d)
{
const Standard_Real aSqMinSize =
this->getParameters().MinSize * this->getParameters().MinSize;
IMeshData::MapOfInteger aUsedNodes;
IMeshData::ListOfInteger& aCirclesList =
const_cast<BRepMesh_CircleTool&>(*myCircles).Select(
@@ -430,7 +458,7 @@ private:
const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]);
const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d());
if (thePnt3d.SquareDistance(aPoint) < aSqMinSize)
if (thePnt3d.SquareDistance(aPoint) < mySqMinSize)
{
return Standard_True;
}
@@ -443,6 +471,7 @@ private:
private:
Standard_Real myMaxSqDeflection;
Standard_Real mySqMinSize;
Standard_Boolean myIsAllDegenerated;
Handle(IMeshData::MapOfOrientedEdges) myCouplesMap;
Handle(IMeshData::ListOfPnt2d) myControlNodes;

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")
if (iGenS == 0)
{
return Standard_False;
}
if (iGenS == 1)
{
return myBuiltShapes(iGenS, 1);
}
else
{
return myBuiltShapes(iGenS, 1) && myUsedShapes(iGenS, 1);
}
}

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

@@ -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

@@ -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

@@ -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,12 +538,33 @@ static void ReconstructMissedSeam(const TopTools_SequenceOfShape& theEdges,
//Build missed seam edge
theLastVertexOfSeam = TopExp::FirstVertex(theNextEdge, Standard_True); //with orientation
TopoDS_Vertex V1, V2;
Standard_Real Param1, Param2, anU = 0.;
Handle(Geom_Curve) Uiso;
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);
Standard_Real anU = (CurTol < LastTol)? theCurPoint.X() : theStartOfNextEdge.X();
Handle(Geom_Curve) Uiso = RefSurf->UIso(anU);
TopoDS_Vertex V1, V2;
Standard_Real Param1, Param2;
anU = (CurTol < LastTol)? theCurPoint.X() : theStartOfNextEdge.X();
Uiso = RefSurf->UIso(anU);
if (Ydir > 0)
{
V1 = theCurVertex; V2 = theLastVertexOfSeam;
@@ -552,7 +575,19 @@ static void ReconstructMissedSeam(const TopTools_SequenceOfShape& theEdges,
V1 = theLastVertexOfSeam; V2 = theCurVertex;
Param1 = theStartOfNextEdge.Y(); Param2 = theCurPoint.Y();
}
}
else
{
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,
@@ -567,21 +602,61 @@ static void ReconstructMissedSeam(const TopTools_SequenceOfShape& theEdges,
}
/////////////////////////////////////
Handle(Geom2d_Line) PC1 = new Geom2d_Line(gp_Pnt2d(anU, Vorigin), gp_Dir2d(0., 1.));
gp_Vec2d Offset(theUperiod, 0.);
Handle(Geom2d_Curve) PC2 = Handle(Geom2d_Curve)::DownCast(PC1->Copy());
if (Ydir > 0)
Offset *= -1;
Handle(Geom2d_Curve) PC2 = Handle(Geom2d_Curve)::DownCast(PC1->Copy());
PC2->Translate(Offset);
BRep_Builder BB;
if (Ydir > 0)
BB.UpdateEdge(MissedSeam, PC1, PC2, theFrefFace, 0.);
else
BB.UpdateEdge(MissedSeam, PC2, PC1, theFrefFace, 0.);
BB.Continuity(MissedSeam, theFrefFace, theFrefFace, aContinuity);
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,128 +676,78 @@ 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_Boolean ToModify = Standard_False,
ToTranslate = Standard_False, Y_Reverse = Standard_False;
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;
gp_Vec2d Translation(0.,0.);
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);
//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_Boolean X_Reverse = Standard_False, Y_Reverse = Standard_False;
Standard_Real u_dx, v_dx, u_dy, v_dy;
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;
gp_Ax3 AxisOfSurfFace = ElemSurfFace->Position();
gp_Ax3 AxisOfRefSurf = ElemRefSurf->Position();
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_Pnt OriginRefSurf = AxisOfRefSurf.Location();
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)
Y_Reverse = Standard_True;
}
else if (v_dy < vv)
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;
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());
ToTranslate = !(Translation.XY().IsEqual(gp_XY(0.,0.), Precision::PConfusion()));
aTrsf.SetTranslationPart(Translation);
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);
BB.UpdateEdge(anEdge, aNewPCurve, theRefFace, 0.);
@@ -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) {
@@ -2009,9 +2040,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 +2127,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 +2141,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 +2193,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 +2216,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 +2477,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 +2561,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

@@ -19,7 +19,7 @@ nurbsconvert result result
incmesh result 0.15 -a 20
tricheck result
checktrinfo result -tri 193 -nod 147 -defl 0.04209 -tol_abs_defl 1.0e-6
checktrinfo result -tri 191 -nod 146 -defl 0.0362596 -tol_abs_defl 1.0e-6
vinit

View File

@@ -1,10 +1,7 @@
puts "========"
puts "OCC25883"
puts "========"
puts "============================================================="
puts "OCC25883: BRepOffsetAPI_MakePipeShell produces invalid result"
puts "============================================================="
puts ""
#######################################################
# BRepOffsetAPI_MakePipeShell produces invalid result
#######################################################
restore [locate_data_file OCC25883_shape.brep] a
@@ -16,12 +13,20 @@ mksweep a_1
addsweep a_2
buildsweep res
donly res
fit
set bug_info [checkshape res]
if {[string compare $bug_info "This shape seems to be valid"] != 0} {
puts "ERROR: OCC25883 is reproduced."
}
set tolres [checkmaxtol res]
if { ${tolres} > 1.e-4} {
puts "Error: bad tolerance of result"
}
explode res
mksurface surf2 res_2
donly surf2
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -33,4 +33,4 @@ checkprops r4 -s 10944.1
explode pr_1 v
generated r3 sweep_hist pr_1_3
checkprops r3 -l 130.036
checkprops r3 -l 65.0179

View File

@@ -1,3 +1,5 @@
puts "TODO OCC21413 ALL: bad accuracy of approximation"
puts "========"
puts "OCC21413"
puts "========"
@@ -8,6 +10,12 @@ puts ""
restore [locate_data_file bug21413_dc1_err.draw] a
tuyau result a 1
set log [tuyau result a 1]
regexp {Accuracy of approximation = ([0-9+-.eE]*)} $log full accuracy
if { ${accuracy} > 0.0001} {
puts "Error: bad accuracy of approximation"
}
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,4 +1,4 @@
puts "TODO OCC23942 ALL: is not equal"
puts "TODO OCC21413 ALL: bad accuracy of approximation"
puts "========"
puts "OCC23942"
@@ -12,7 +12,13 @@ puts ""
### 1
#
interpol c [locate_data_file bug23942_points.txt]
tuyau r_1 c 5
set log [tuyau r_1 c 5]
regexp {Accuracy of approximation = ([0-9+-.eE]*)} $log full accuracy
if { ${accuracy} > 0.0001} {
puts "Error: bad accuracy of approximation"
}
decho off
dlog reset
@@ -38,7 +44,13 @@ puts "VKnots_1 = ${VKnots_1}"
#
save c ${imagedir}/cc
restore ${imagedir}/cc
tuyau r_2 cc 5
set log [tuyau r_2 cc 5]
regexp {Accuracy of approximation = ([0-9+-.eE]*)} $log full accuracy
if { ${accuracy} > 0.0001} {
puts "Error: bad accuracy of approximation"
}
decho off
dlog reset

View File

@@ -0,0 +1,40 @@
puts "============================================================================"
puts "0026876: Modeling Algorithms - Boolean algorithm fails or produce faulty shape"
puts "============================================================================"
puts ""
restore [locate_data_file bug26883_object.brep] o
restore [locate_data_file bug26883_fuse_tool1.brep] ft1
restore [locate_data_file bug26883_fuse_tool2.brep] ft2
restore [locate_data_file bug26876_cut_tool1.brep] ct1
restore [locate_data_file bug26876_cut_tool2.brep] ct2
bclearobjects
bcleartools
baddobjects o
baddtools ft1 ft2
bfillds
bbop result_fuse 1
checkshape result_fuse
if {![regexp "OK" [bopcheck result_fuse]]} {
puts "Error: the result of FUSE operation is a self-interfering shape"
}
checkprops result_fuse -s 2117 -v 607.602
checknbshapes result_fuse -wire 52 -face 44 -shell 3 -solid 1 -t
bclearobjects
bcleartools
baddobjects result_fuse
baddtools ct1 ct2
bfillds
bbop result 2
checkshape result
if {![regexp "OK" [bopcheck result]]} {
puts "Error: the result of CUT operation is a self-interfering shape"
}
checkprops result -s 2112.67 -v 607.132
checknbshapes result -wire 50 -face 42 -shell 2 -solid 1 -t
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,6 +1,3 @@
puts "TODO OCC26882 ALL: Error : is WRONG because number of VERTEX entities in shape"
puts "TODO OCC26882 ALL: Error : is WRONG because number of EDGE entities in shape"
puts "========"
puts "OCC26882"
puts "========"

View File

@@ -15,10 +15,37 @@ baddobjects b1
baddtools b2
bfillds
bbop result 1
bbop r_0 0
bbop r_1 1
bbop r_2 2
bbop r_3 3
bbop r_4 4
bbuild r_5
checkshape result
checkprops result -s 2116.44 -v 607.276
checknbshapes result -wire 39 -face 32 -shell 3 -solid 1
foreach i { 0 1 2 3 4 5} {
checkshape r_$i
if {![regexp "OK" [bopcheck r_$i]]} {
puts "Error: r_$i is self-intersecting shape"
}
}
checkview -display result -2d -path ${imagedir}/${test_image}.png
checkprops r_0 -s 9.84822 -v 0.639566
checknbshapes r_0 -wire 7 -face 5 -shell 1 -solid 1 -t
checkprops r_1 -s 2116.61 -v 607.386
checknbshapes r_1 -wire 40 -face 34 -shell 3 -solid 1 -t
checkprops r_2 -s 2110.46 -v 606.532
checknbshapes r_2 -wire 36 -face 30 -shell 3 -solid 2 -t
checkprops r_3 -s 15.9958 -v 0.215358
checknbshapes r_3 -wire 11 -face 9 -shell 2 -solid 2 -t
checkprops r_4 -l 24.818
checksection r_4 -r 0
checkprops r_5 -s 2146.15 -v 608.026
checknbshapes r_5 -wire 47 -face 39 -shell 6 -solid 5 -t
checkview -display r_1 -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,48 @@
puts "========"
puts "0029843: Modeling Algorithms - Boolean FUSE produces incorrect result"
puts "========"
puts ""
restore [locate_data_file bug29843.brep] s
explode s
bclearobjects
bcleartools
baddobjects s_1
baddtools s_2
bfillds
bbop r_0 0
bbop r_1 1
bbop r_2 2
bbop r_3 3
bbop r_4 4
bbuild r_5
foreach i { 0 1 2 3 4 5} {
checkshape r_$i
if {![regexp "OK" [bopcheck r_$i]]} {
puts "Error: r_$i is self-intersecting shape"
}
}
checkprops r_0 -s 9.84429 -v 0.639311
checknbshapes r_0 -wire 7 -face 5 -shell 1 -solid 1 -t
checkprops r_1 -s 2121.39 -v 612.41
checknbshapes r_1 -wire 38 -face 32 -shell 2 -solid 1 -t
checkprops r_2 -s 2113.85 -v 611.569
checknbshapes r_2 -wire 32 -face 26 -shell 2 -solid 1 -t
checkprops r_3 -s 15.9893 -v 0.215264
checknbshapes r_3 -wire 11 -face 9 -shell 2 -solid 2 -t
checkprops r_4 -l 24.9725
checksection r_4 -r 2
checkprops r_5 -s 2139.68 -v 612.402
checknbshapes r_5 -wire 44 -face 36 -shell 5 -solid 4 -t
checkview -display r_0 -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,51 @@
puts "========"
puts "0029843: Modeling Algorithms - Boolean FUSE produces incorrect result"
puts "========"
puts ""
puts "Boolean operation fails on the objects located far from origin (1.e+8)"
restore [locate_data_file bug29843_loc.brep] s
explode s
bclearobjects
bcleartools
baddobjects s_1
baddtools s_2
bfillds
bbop r_0 0
bbop r_1 1
bbop r_2 2
bbop r_3 3
bbop r_4 4
bbuild r_5
foreach i { 0 1 2 3 4 5} {
checkshape r_$i
if {![regexp "OK" [bopcheck r_$i]]} {
puts "Error: r_$i is self-intersecting shape"
}
}
checkprops r_0 -s 62185.2 -v 1.1761e+06
checknbshapes r_0 -vertex 6 -edge 9 -wire 5 -face 5 -shell 1 -solid 1 -t
checkprops r_1 -s 1.85327e+06 -v 5.92874e+07
checknbshapes r_1 -vertex 15 -edge 24 -wire 11 -face 11 -shell 1 -solid 1 -t
checkprops r_2 -s 1.85376e+06 -v 5.78639e+07
checknbshapes r_2 -vertex 14 -edge 21 -wire 9 -face 9 -shell 1 -solid 1 -t
checkprops r_3 -s 37189.7 -v 247431
checknbshapes r_3 -vertex 6 -edge 9 -wire 5 -face 5 -shell 1 -solid 1 -t
checkprops r_4 -l 952.189
checksection r_4 -r 2
checknbshapes r_4 -vertex 6 -edge 7 -t
checkprops r_5 -s 2.01533e+06 -v 6.04635e+07
checknbshapes r_5 -vertex 15 -edge 26 -wire 15 -face 15 -shell 3 -solid 3 -t
checkview -display r_2 -2d -path ${imagedir}/${test_image}.png

View File

@@ -10,7 +10,7 @@ mkface f1 s 0 2*pi 0.785398163397448 1.5707963267949
prism r1 f1 0 0 2
savehistory h1
set s1 [dump h1]
if { !([regexp "0 Deleted" $s1] && [regexp "2 Generated" $s1])} {
if { !([regexp "0 Deleted" $s1] && [regexp "3 Generated" $s1])} {
puts "Error: wrong history h1"
}
#
@@ -18,6 +18,6 @@ mkface f2 s 0 5 0.785398163397448 1.5707963267949
prism r2 f2 0 0 2
savehistory h2
set s2 [dump h2]
if { !([regexp "0 Deleted" $s2] && [regexp "6 Generated" $s2])} {
if { !([regexp "0 Deleted" $s2] && [regexp "7 Generated" $s2])} {
puts "Error: wrong history h2"
}

View File

@@ -0,0 +1,30 @@
puts "======================================================="
puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
puts "======================================================="
puts ""
restore [locate_data_file bug30386_shapes.brep] s
explode s
bclearobjects
bcleartools
baddobjects s_1
baddtools s_2
bfillds
bbop r0 0
bbop r2 2
foreach r {r0 r2} {
checkshape $r
if {![regexp "OK" [bopcheck $r]]} {
puts "Error: the $r is a self-interfering shape"
}
}
checknbshapes r0 -wire 6 -face 6 -shell 0 -solid 0 -t
checkprops r0 -s 1.0852
checknbshapes r2 -wire 546 -face 533 -shell 12 -solid 12 -t
checkprops r2 -s 223.275 -v 123.21
checkview -display r2 -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,18 @@
puts "REQUIRED All: Error: Boolean operation of the given type is not allowed on the given inputs"
puts "======================================================="
puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
puts "======================================================="
puts ""
restore [locate_data_file bug30386_shapes.brep] s
explode s
# just to avoid intersection
ttranslate s_2 10 0 0
bclearobjects
bcleartools
baddobjects s_1
baddtools s_2
bfillds
# try to perform fuse operation - error is expected
bbop r1 1

View File

@@ -0,0 +1,18 @@
puts "REQUIRED All: Error: Boolean operation of the given type is not allowed on the given inputs"
puts "======================================================="
puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
puts "======================================================="
puts ""
restore [locate_data_file bug30386_shapes.brep] s
explode s
# just to avoid intersection
ttranslate s_2 10 0 0
bclearobjects
bcleartools
baddobjects s_1
baddtools s_2
bfillds
# try to perform CUT21 operation - error is expected
bbop r3 3

View File

@@ -0,0 +1,50 @@
puts "======================================================="
puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
puts "======================================================="
puts ""
# prepare the first argument - compound of mutlti-dimensional shapes
vertex v 0 0 2
line l 5 5 0 0 0 1
mkedge e l -10 10
plane p 0 0 1 0 0 1
mkface f p -15 15 -15 15
box b 8 8 8 5 5 5
bclearobjects
bcleartools
baddobjects v e f b
bfillds
bbuild s1
# second argument - solid
box s2 10 10 10
bclearobjects
bcleartools
baddobjects s1
baddtools s2
bfillds
# it is allowed to perform only CUT and COMMON operations
bbop r0 0
bbop r2 2
foreach r {r0 r2} {
checkshape $r
if {![regexp "OK" [bopcheck $r]]} {
puts "Error: the $r is a self-interfering shape"
}
}
checknbshapes r0 -vertex 16 -edge 18 -wire 7 -face 7 -shell 1 -solid 1 -t
checkprops r0 -s 124
explode r0 so
checkprops r0_1 -v 8
checknbshapes r2 -vertex 24 -edge 30 -wire 11 -face 10 -shell 1 -solid 1 -t
checkprops r2 -s 950
explode r2 so
checkprops r2_1 -v 117
checkview -display r2 -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,46 @@
puts "REQUIRED All: Error: Boolean operation of the given type is not allowed on the given inputs"
puts "======================================================="
puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
puts "======================================================="
puts ""
# prepare the first argument - compound of mutlti-dimensional shapes
vertex v 0 0 2
line l 5 5 0 0 0 1
mkedge e l -10 10
plane p 0 0 1 0 0 1
mkface f p -15 15 -15 15
box b 8 8 8 5 5 5
bclearobjects
bcleartools
baddobjects v e f b
bfillds
bbuild s1
# second argument - compound of solid and face
box b2 10 10 10
bclearobjects
bcleartools
baddobjects f
baddtools b2
bfillds
bbuild s2
# only common operation should be allowed
bclearobjects
bcleartools
baddobjects s1
baddtools s2
bfillds
if {[regexp "Error: Boolean operation of the given type is not allowed on the given inputs" [bbop r 0]]} {
puts "Error: COMMON Operation must be allowed on any types of arguments"
}
foreach i {1 2 3} {
if {![regexp "Error: Boolean operation of the given type is not allowed on the given inputs" [bbop r $i]]} {
puts "Error: Operation must not be allowed"
}
}

View File

@@ -1,6 +1,6 @@
puts "================================================================"
puts "OCC30597: BRepOffsetAPI_MakePipeShell raises Standard_RangeError"
puts "================================================================"
puts "================================================================================"
puts "OCC30597: Result of BRepOffsetAPI_MakePipeShell doesn't match the given profiles"
puts "================================================================================"
puts ""
restore [locate_data_file bug30597_compound.brep] a
@@ -16,4 +16,32 @@ addsweep a_3_1 a_1_2
buildsweep result
checkprops result -s 0.95884
checkprops result -s 0.880677
explode result e
explode a_2_1
mkcurve c2 a_2_1_1
cvalue c2 pi x2 y2 z2
vertex v2 x2 y2 z2
distmini d2 v2 result_2
if {[dval d2_val] > 1.e-7} {
puts "Error: result is far from first profile"
}
explode a_3_1
mkcurve c3 a_3_1_1
cvalue c3 pi x3 y3 z3
vertex v3 x3 y3 z3
distmini d3 v3 result_3
if {[dval d3_val] > 1.e-7} {
puts "Error: result is far from second profile"
}
smallview
donly result a_2_1 a_3_1
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,15 @@
puts "========"
puts "0031031: Incorrect result is returned from BRepPrimAPI_MakePrism::Generated()"
puts "========"
puts ""
pload MODELING
vertex v1 0 0 0
prism r1 v1 0 0 2
savehistory h1
set s1 [dump h1]
if { !([regexp "0 Deleted" $s1] && [regexp "1 Generated" $s1])} {
puts "Error: wrong history h1"
}

View File

@@ -0,0 +1,22 @@
puts "======================================================="
puts "OCC31066: Infinite loop in ShapeUpgrade_UnifySameDomain"
puts "======================================================="
puts ""
pload MODELING DATAEXCHANGE
stepread [locate_data_file bug31066.stp] a *
unifysamedom result a_1
checkshape result
checknbshapes result -solid 1 -shell 1 -face 140 -wire 174 -edge 352 -vertex 208
set tolres [checkmaxtol result]
if { ${tolres} > 0.001} {
puts "Error: bad tolerance of result"
}
checkprops result -v 139105

View File

@@ -0,0 +1,18 @@
puts "============================================================="
puts "OCC31187: Unify same domain algorithm produces invalid shape."
puts "============================================================="
puts ""
restore [locate_data_file bug31187_fuse.brep] a
unifysamedom result a -t 1.e-4 -a 1.e-6
checkshape result
checknbshapes result -solid 1 -shell 1 -face 13 -wire 13 -edge 36 -vertex 25
set tolres [checkmaxtol result]
if { ${tolres} > 6.e-5} {
puts "Error: bad tolerance of result"
}

View File

@@ -0,0 +1,13 @@
puts "======================================================="
puts "0031242: Scaling with different coefficients along axes produces invalid shape"
puts "======================================================="
puts ""
restore [locate_data_file bug31242.brep] f
scalexyz result f 1 1 0.25
checkshape result
checkprops result -s 685.043
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,8 @@
puts "======================================================="
puts "0031294: Modeling Algorithms - Regression relatively 7.3.0."
puts "Crash in method BRepPrimAPI_MakePrism::Generated(...) if input sub-shape does not belong to the base shape"
puts "======================================================="
puts ""
pload QAcommands
OCC31294

View File

@@ -0,0 +1,46 @@
puts "======================================================="
puts "0031404: Modeling Algorithms - BOP Fuse produces a self-interfering or a good shape depending on the order of arguments"
puts "======================================================="
puts ""
psphere sph1 25
plane pln2 32, 68, -27
psphere sph2 pln2 75
bfuse f1 sph1 sph2
savehistory h1
bfuse f2 sph2 sph1
savehistory h2
explode sph1 f
modified ff1 h1 sph1_1
modified ff2 h2 sph1_1
foreach r {f1 f2} {
checkshape $r
if {![regexp "OK" [bopcheck $r]]} {
puts "Error: the $r is a self-interfering shape"
}
if { [checkmaxtol $r] > 2.e-7 } {
puts "Error: $r has bad tolerance"
}
}
checknbshapes f1 -wire 3 -face 2 -edge 9 -vertex 6
checknbshapes f2 -wire 3 -face 2 -edge 9 -vertex 6
checkprops f1 -s 74192.6
checkprops f2 -s 74192.6
view 1 -2D- 0 200 500 300
pcurve ff1
pcurve ff2
2dtranslate ff2_6 pi 0
donly ff1_6 ff2_6
2dfit
checklength ff1_6 -l 7.167
checklength ff2_6 -l 7.167
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,13 @@
puts "========"
puts "0031407: Extrema does not process parallel circles correctly"
puts "========"
puts ""
circle c1 0 0 0 0 0 1 5
circle c2 0 0 0 0 0 1 10
if { [regexp "Infinite number of extremas" [extrema c1 c2]] == 1} {
puts "OK : Circles are treated as concentric"
} else {
puts "Error : Extrema does not find the circles are parallel"
}

View File

@@ -0,0 +1,13 @@
puts "========"
puts "0031407: Extrema does not process parallel circles correctly"
puts "========"
puts ""
circle c1 0 0 0 0 0 -1 5
circle c2 0 0 0 0 0 1 10
if { [regexp "Infinite number of extremas" [extrema c1 c2]] == 1} {
puts "OK : Circles are treated as concentric"
} else {
puts "Error : Extrema does not find the circles are parallel"
}

View File

@@ -0,0 +1,20 @@
puts "========"
puts "0031407: Extrema does not process parallel circles correctly"
puts "========"
puts ""
circle c1 0 0 0 0 0 1 5
circle c2 0 0 0 0 0 1 10
trim cc1 c1 0 2
trim cc2 c2 2 4
set res_extrema [extrema cc1 cc2]
if { [regexp "Infinite number of extremas" $res_extrema] == 0} {
if {[llength $res_extrema] != 1} {
puts "Error : expected 1 extrema, but found [llength $res_extrema]"
}
} else {
puts "Error : Infinite number of extremas is found"
}

View File

@@ -0,0 +1,18 @@
puts "======================================================="
puts "0031415: Modeling Algorithms - Solid classifier works incorrectly on a cylinder"
puts "======================================================="
puts ""
restore [locate_data_file bug31415_1.brep] comp
restore [locate_data_file bug31415_2.brep] cyl
explode comp v
mkpoint p1 comp_1
mkpoint p2 comp_2
mkpoint p3 comp_3
mkpoint p4 comp_4
foreach p {p1 p2 p3 p4} {
if {![regexp "IN" [bclassify cyl $p]]} {
puts "Error: classyfication of $p is wrong"
}
}

View File

@@ -0,0 +1,20 @@
puts "============================================"
puts "OCC31441: UnifySameDomain corrupts the shape"
puts "============================================"
puts ""
brestore [locate_data_file bug31441.brep] a
unifysamedom result a
checkshape result
checknbshapes result -solid 1 -shell 2 -face 46 -wire 48 -edge 128 -vertex 84
set tolres [checkmaxtol result]
if { ${tolres} > 2.e-7} {
puts "Error: bad tolerance of result"
}
checkprops result -v 1.10788

View File

@@ -0,0 +1,34 @@
puts "========"
puts "0031460: Modeling Algorithms - Regression: Revolution not done."
puts "========"
puts ""
circle cir 3 2.9999999999989 0 0 0 -1 -1 0 0 3
trim cir cir 4.71238898038469 6.28318530717959
mkedge e cir
## sector
revol r10 e 0 0 0 1 0 0 10 1
if { [isdraw r10] == 1 } {
if { [regexp "valid" [checkshape r10]] && [regexp "OK" [bopcheck r10 4]]} {
puts "OK: valid shape is created"
} else {
puts "Error: algorithm created wrong shape"
}
} else {
puts "Error: algorithm did not create shape"
}
## full revol
revol r360 e 0 0 0 1 0 0 360 1
if { [isdraw r360] == 1 } {
if { [regexp "valid" [checkshape r360]] && [regexp "OK" [bopcheck r360 4]]} {
puts "OK: valid shape is created"
} else {
puts "Error: algorithm created wrong shape"
}
} else {
puts "Error: algorithm did not create shape"
}

View File

@@ -0,0 +1,44 @@
puts "========"
puts "0031462: Modeling Algorithms - BOP result depends on the arguments order"
puts "========"
puts ""
restore [locate_data_file bug31462_obj.brep] s1
restore [locate_data_file bug31462_tools.brep] s2
tcopy s1 obj
tcopy s2 sx
bclearobjects
bcleartools
baddobjects obj
eval baddtools [explode sx]
bfillds
bsplit result1
checkshape result1
if {![regexp "This shape seems to be OK" [bopcheck result1]]} {
puts "Error: self-interfering result"
}
checknbshapes result1 -wire 19 -face 18 -shell 3 -solid 2
checkprops result1 -s 103.955 -v 38.7982
tcopy s1 obj
tcopy s2 sx
bclearobjects
bcleartools
baddobjects obj
explode sx
baddtools sx_4 sx_5 sx_6 sx_3 sx_2 sx_1
bfillds
bsplit result2
checkshape result2
if {![regexp "This shape seems to be OK" [bopcheck result2]]} {
puts "Error: self-interfering result"
}
checknbshapes result2 -ref [nbshapes result1]
checkprops result2 -equal result1
checkview -display result1 -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,36 @@
puts "================================================================="
puts "OCC31470: BOP common produces empty result (box and holed sphere)"
puts "================================================================="
puts ""
plane pln1 51.899912462 99.996691888 62.33204004
psphere s1 pln1 15
psphere s2 pln1 10
bcut ss s1 s2
box bb 100 100 100
bcommon result bb ss
savehistory hh
explode ss f
modified ff hh ss_1
generated ee hh ss_1
checkshape result
checknbshapes result -solid 1 -shell 1 -face 3 -wire 6 -edge 8 -vertex 6
set tolres [checkmaxtol result]
if { ${tolres} > 2.e-7} {
puts "Error: bad tolerance of result"
}
checkprops result -v 4975.49
v2d
pcurve pc ee ff
trim pc pc
2dfit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -4,13 +4,6 @@ puts "=========="
cpulimit 100
puts "TODO OCC30438 ALL: Error : The area of result shape is"
puts "TODO OCC30438 ALL: Error : The volume of result shape is"
puts "TODO OCC30438 ALL: Error : is WRONG because number of SHELL"
puts "TODO OCC30438 ALL: Error : is WRONG because number of SOLID"
puts "TODO OCC30438 ALL: Error: bopargcheck has found some faulties in result"
restore [locate_data_file bug29523_cut_extrudewire07.brep] sw
restore [locate_data_file bug29523_cut_toolwire07.brep] tw
@@ -219,7 +212,7 @@ if {[regexp "Faulties" [bopargcheck result]]} {
# the dimensions of the shape "result" are about 1.0e+5.
# So, this tolerance seems to be OK.
checkmaxtol result -ref 18.634531507134731
checkmaxtol result -ref 1.7319951447770465
smallview
don result sw tw