1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
nbv
86b52ffdea 0025416: Wrong section curve
patch #25416 to OCCT 6.7.0
2014-10-30 17:00:45 +03:00
23 changed files with 3352 additions and 3148 deletions

View File

@@ -74,7 +74,6 @@ is
class CheckerSI;
class ArgumentAnalyzer;
class CheckResult;
class ShellSplitter;
--
-- pointers
--

View File

@@ -57,8 +57,6 @@
#include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BRepBndLib.hxx>
#include <Bnd_Box.hxx>
static
@@ -446,7 +444,6 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
}
//
// 2. Find outer growth shell that is most close to each hole shell
BOPCol_ListOfShape anUnUsedHoles;
aIt2.Initialize(aHoleWires);
for (; aIt2.More(); aIt2.Next()) {
const TopoDS_Shape& aHole = aIt2.Value();
@@ -484,26 +481,8 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
aMSH.Bind(aF, aLH);
}
}
else {
anUnUsedHoles.Append(aHole);
}
}// for (; aIt2.More(); aIt2.Next())
//
if (anUnUsedHoles.Extent()) {
// add the infinite face to new faces
Bnd_Box aBox;
BRepBndLib::Add(myFace, aBox);
if (aBox.IsOpenXmin() || aBox.IsOpenXmax() ||
aBox.IsOpenYmin() || aBox.IsOpenYmax() ||
aBox.IsOpenZmin() || aBox.IsOpenZmax()) {
TopoDS_Face aFace;
aBB.MakeFace(aFace, aS, aLoc, aTol);
//
aNewFaces.Append(aFace);
aMSH.Bind(aFace, anUnUsedHoles);
}
}
//
// 3. Add aHoles to Faces
aItMSH.Initialize(aMSH);
for (; aItMSH.More(); aItMSH.Next()) {

View File

@@ -6,35 +6,29 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//
#include <BOPAlgo_BuilderSolid.ixx>
//
#include <NCollection_List.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_UBTreeFiller.hxx>
//
#include <gp_Pnt2d.hxx>
#include <gp_Pln.hxx>
#include <gp_Vec.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
//
#include <TColStd_MapIntegerHasher.hxx>
//
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Geom2d_Curve.hxx>
//
#include <TopAbs.hxx>
//
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
@@ -46,32 +40,25 @@
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
//
#include <BRepTools.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
//
#include <BRepBndLib.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
//
#include <BOPTools_AlgoTools.hxx>
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
#include <BOPTools.hxx>
#include <BOPCol_ListOfShape.hxx>
#include <BOPCol_MapOfOrientedShape.hxx>
//
#include <NCollection_List.hxx>
//
#include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BOPCol_ListOfInteger.hxx>
//
#include <BOPDS_BoxBndTree.hxx>
#include <BOPTools.hxx>
#include <BOPTools_CoupleOfShape.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools3D.hxx>
//
#include <BOPInt_Context.hxx>
//
#include <BOPAlgo_ShellSplitter.hxx>
#include <BOPCol_DataMapOfIntegerShape.hxx>
#include <BOPTools_CoupleOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
static
Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
@@ -87,63 +74,14 @@ static
void MakeInternalShells(const BOPCol_MapOfShape& ,
BOPCol_ListOfShape& );
//=======================================================================
//class : BOPAlgo_BuilderSolid_ShapeBox
//purpose : Auxiliary class
//=======================================================================
class BOPAlgo_BuilderSolid_ShapeBox {
public:
BOPAlgo_BuilderSolid_ShapeBox() {
myIsHole=Standard_False;
};
//
~BOPAlgo_BuilderSolid_ShapeBox() {
};
//
void SetShape(const TopoDS_Shape& aS) {
myShape=aS;
};
//
const TopoDS_Shape& Shape()const {
return myShape;
};
//
void SetBox(const Bnd_Box& aBox) {
myBox=aBox;
};
//
const Bnd_Box& Box()const {
return myBox;
};
//
void SetIsHole(const Standard_Boolean bFlag) {
myIsHole=bFlag;
};
//
Standard_Boolean IsHole()const {
return myIsHole;
};
//
protected:
Standard_Boolean myIsHole;
TopoDS_Shape myShape;
Bnd_Box myBox;
};
//
typedef NCollection_DataMap
<Standard_Integer,
BOPAlgo_BuilderSolid_ShapeBox,
TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB;
//
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
//
//
static
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
//=======================================================================
//function :
//purpose :
//=======================================================================
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
:
BOPAlgo_BuilderArea()
{
@@ -152,8 +90,7 @@ BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
//function :
//purpose :
//=======================================================================
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid
(const Handle(NCollection_BaseAllocator)& theAllocator)
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator)
:
BOPAlgo_BuilderArea(theAllocator)
{
@@ -162,18 +99,20 @@ BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid
//function : ~
//purpose :
//=======================================================================
BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
{
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::Perform()
void BOPAlgo_BuilderSolid::Perform()
{
myErrorStatus=0;
//
if (myContext.IsNull()) {
//myErrorStatus=11;// Null Context
//return;
myContext=new BOPInt_Context;
}
//
@@ -188,6 +127,7 @@ void BOPAlgo_BuilderSolid::Perform()
aBB.Add(aC, aF);
}
//
//
PerformShapesToAvoid();
if (myErrorStatus) {
return;
@@ -197,12 +137,10 @@ void BOPAlgo_BuilderSolid::Perform()
if (myErrorStatus) {
return;
}
//
PerformAreas();
if (myErrorStatus) {
return;
}
//
PerformInternalShapes();
if (myErrorStatus) {
return;
@@ -212,7 +150,7 @@ void BOPAlgo_BuilderSolid::Perform()
//function :PerformShapesToAvoid
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
{
Standard_Boolean bFound;
Standard_Integer i, iCnt, aNbE, aNbF;
@@ -233,10 +171,7 @@ void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (!myShapesToAvoid.Contains(aF)) {
BOPTools::MapShapesAndAncestors(aF,
TopAbs_EDGE,
TopAbs_FACE,
aMEF);
BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
}
}
aNbE=aMEF.Extent();
@@ -286,51 +221,151 @@ void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
break;
}
//
}//for(;;) {
}//while (1)
}
//=======================================================================
//function : PerformLoops
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformLoops()
void BOPAlgo_BuilderSolid::PerformLoops()
{
Standard_Integer iErr;
BOPCol_ListIteratorOfListOfShape aIt;
TopoDS_Iterator aItS;
BOPCol_MapIteratorOfMapOfOrientedShape aItM;
BOPAlgo_ShellSplitter aSSp;
//
myErrorStatus=0;
//
myLoops.Clear();
//
// 1. Shells Usual
aIt.Initialize (myShapes);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (!myShapesToAvoid.Contains(aF)) {
aSSp.AddStartElement(aF);
}
}
Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA;
Standard_Integer i;
TopAbs_Orientation anOr;
TopoDS_Edge aEL;
BRep_Builder aBB;
TopoDS_Iterator aItS;
//
aSSp.Perform();
iErr=aSSp.ErrorStatus();
if (iErr) {
return;
}
BOPCol_ListIteratorOfListOfShape aItF, aIt;
BOPCol_MapIteratorOfMapOfOrientedShape aItM;
BOPTools_CoupleOfShape aCSOff;
//
BOPCol_MapOfOrientedShape AddedFacesMap;
BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
//
const BOPCol_ListOfShape& aLSh=aSSp.Shells();
aIt.Initialize (aLSh);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSh=aIt.Value();
myLoops.Append(aSh);
}
//=================================================
//
// 2. Post Treatment
Standard_Integer aNbFA;
BRep_Builder aBB;
BOPCol_MapOfOrientedShape AddedFacesMap;
BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
// 1. Shells Usual
//
aItF.Initialize (myShapes);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Shape& aFF = aItF.Value();
BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
}
//
aItF.Initialize (myShapes);
for (i=1; aItF.More(); aItF.Next(), ++i) {
const TopoDS_Shape& aFF = aItF.Value();
if (myShapesToAvoid.Contains(aFF)) {
continue;
}
if (!AddedFacesMap.Add(aFF)) {
continue;
}
//
// make a new shell
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
aBB.Add(aShell, aFF);
//
aMEFP.Clear();
BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
//
// loop on faces added to Shell; add their neighbor faces to Shell and so on
TopoDS_Iterator aItAddedF (aShell);
for (; aItAddedF.More(); aItAddedF.Next()) {
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
//
// loop on edges of aF; find a good neighbor face of aF by aE
TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
for (; aEdgeExp.More(); aEdgeExp.Next()) {
const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
//
//1
if (aMEFP.Contains(aE)) {
const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
aNbFP=aLFP.Extent();
if (aNbFP>1) {
continue;
}
}
//2
anOr=aE.Orientation();
if (anOr==TopAbs_INTERNAL) {
continue;
}
//3
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
// candidate faces list
const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
aNbLF=aLF.Extent();
if (!aNbLF) {
continue;
}
//
// try to select one of neighbors
// check if a face already added to Shell shares E
Standard_Boolean bFound;
BOPCol_ListIteratorOfListOfShape aItLF;
BOPTools_ListOfCoupleOfShape aLCSOff;
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
if (myShapesToAvoid.Contains(aFL)) {
continue;
}
if (aF.IsSame(aFL)) {
continue;
}
if (AddedFacesMap.Contains(aFL)){
continue;
}
//
bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
if (!bFound) {
continue;
}
//
aCSOff.SetShape1(aEL);
aCSOff.SetShape2(aFL);
aLCSOff.Append(aCSOff);
}//for (; aItLF.More(); aItLF.Next()) {
//
aNbOff=aLCSOff.Extent();
if (!aNbOff){
continue;
}
//
TopoDS_Face aSelF;
if (aNbOff==1) {
aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
}
else if (aNbOff>1){
BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext);
}
//
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
aBB.Add(aShell, aSelF);
BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
}
} // for (; aEdgeExp.More(); aEdgeExp.Next()) {
} //for (; aItAddedF.More(); aItAddedF.Next()) {
//
if (IsClosedShell(aShell)) {
myLoops.Append(aShell);
}
} // for (; aItF.More(); aItF.Next()) {
//
// Post Treatment
BOPCol_MapOfOrientedShape aMP;
//
// a. collect all edges that are in loops
@@ -361,7 +396,8 @@ void BOPAlgo_BuilderSolid::PerformLoops()
}
//=================================================
//
// 3.Internal Shells
// 2.Internal Shells
//
myLoopsInternal.Clear();
//
aEFMap.Clear();
@@ -372,9 +408,7 @@ void BOPAlgo_BuilderSolid::PerformLoops()
aItM.Initialize(myShapesToAvoid);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aFF=aItM.Key();
BOPTools::MapShapesAndAncestors(aFF,
TopAbs_EDGE, TopAbs_FACE,
aEFMap);
BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
}
//
aItM.Initialize(myShapesToAvoid);
@@ -397,16 +431,15 @@ void BOPAlgo_BuilderSolid::PerformLoops()
for (; aEdgeExp.More(); aEdgeExp.Next()) {
const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
aIt.Initialize(aLF);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
aItF.Initialize(aLF);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value()));
if (AddedFacesMap.Add(aFL)){
aBB.Add(aShell, aFL);
}
}
}
}
aShell.Closed (BRep_Tool::IsClosed (aShell));
myLoopsInternal.Append(aShell);
}
}
@@ -414,141 +447,85 @@ void BOPAlgo_BuilderSolid::PerformLoops()
//function : PerformAreas
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformAreas()
void BOPAlgo_BuilderSolid::PerformAreas()
{
Standard_Boolean bIsGrowth, bIsHole;
Standard_Integer k,aNbHoles;
myErrorStatus=0;
//
Standard_Boolean bIsGrowthShell, bIsHole;
BRep_Builder aBB;
BOPCol_ListIteratorOfListOfShape aItLS;
TopoDS_Shape anInfinitePointShape;
BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
//
BOPCol_ListOfShape aNewSolids, aHoleShells;
BOPCol_DataMapOfShapeShape aInOutMap;
BOPCol_IndexedMapOfShape aMHF;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPDS_BoxBndTreeSelector aSelector;
BOPDS_BoxBndTree aBBTree;
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
BOPCol_DataMapOfShapeListOfShape aMSH;
BOPCol_DataMapIteratorOfDataMapOfShapeShape aItDMSS;
BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
//
myErrorStatus=0;
BOPCol_IndexedMapOfShape aMHF;
//
myAreas.Clear();
//
// Draft solids [aNewSolids]
aItLS.Initialize(myLoops);
for (k=0; aItLS.More(); aItLS.Next(), ++k) {
TopoDS_Solid aSolid;
Bnd_Box aBox;
BOPAlgo_BuilderSolid_ShapeBox aSB;
aShellIt.Initialize(myLoops);
for ( ; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aShell = aShellIt.Value();
//
const TopoDS_Shape& aShell = aItLS.Value();
aSB.SetShape(aShell);
//
BRepBndLib::Add(aShell, aBox);
bIsHole=Standard_False;
//
bIsGrowth=IsGrowthShell(aShell, aMHF);
if (bIsGrowth) {
bIsGrowthShell=IsGrowthShell(aShell, aMHF);
if (bIsGrowthShell) {
// make a growth solid from a shell
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aShell);
TopoDS_Solid Solid;
aBB.MakeSolid(Solid);
aBB.Add (Solid, aShell);
//
aNewSolids.Append (aSolid);
aSB.SetShape(aSolid);
aNewSolids.Append (Solid);
}
else{
// check if a shell is a hole
//XX
bIsHole=IsHole(aShell, myContext);
//XX
if (bIsHole) {
aHoleShells.Append(aShell);
BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
aSB.SetShape(aShell);
}
else {
// make a growth solid from a shell
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aShell);
TopoDS_Solid Solid;
aBB.MakeSolid(Solid);
aBB.Add (Solid, aShell);
//
aNewSolids.Append (aSolid);
aSB.SetShape(aSolid);
aNewSolids.Append (Solid);
}
}
}
//
aSB.SetBox(aBox);
aSB.SetIsHole(bIsHole);
aDMISB.Bind(k, aSB);
}
// 2. Find outer growth shell that is most close to each hole shell
aShellIt.Initialize(aHoleShells);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aHole = aShellIt.Value();
//
// 2. Prepare TreeFiller
aItDMISB.Initialize(aDMISB);
for (; aItDMISB.More(); aItDMISB.Next()) {
k=aItDMISB.Key();
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
//
bIsHole=aSB.IsHole();
if (bIsHole) {
const Bnd_Box& aBox=aSB.Box();
aTreeFiller.Add(k, aBox);
}
}
//
// 3. Shake TreeFiller
aTreeFiller.Fill();
//
// 4. Find outer growth shell that is most close
// to each hole shell
aItDMISB.Initialize(aDMISB);
for (; aItDMISB.More(); aItDMISB.Next()) {
k=aItDMISB.Key();
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
bIsHole=aSB.IsHole();
if (bIsHole) {
continue;
}
//
const TopoDS_Shape aSolid=aSB.Shape();
const Bnd_Box& aBoxSolid=aSB.Box();
//
aSelector.Clear();
aSelector.SetBox(aBoxSolid);
//
aNbHoles=aBBTree.Select(aSelector);
//
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
//
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
k=aItLI.Value();
const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
const TopoDS_Shape& aHole=aSBk.Shape();
aSolidIt.Initialize(aNewSolids);
for ( ; aSolidIt.More(); aSolidIt.Next()) {
const TopoDS_Shape& aSolid = aSolidIt.Value();
//
if (!IsInside(aHole, aSolid, myContext)){
continue;
}
//
if (aInOutMap.IsBound (aHole)){
const TopoDS_Shape& aHole2=aInOutMap(aHole);
if (IsInside(aHole, aHole2, myContext)) {
if ( aInOutMap.IsBound (aHole)){
const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
if (IsInside(aSolid, aSolid2, myContext)) {
aInOutMap.UnBind(aHole);
aInOutMap.Bind (aHole, aSolid);
}
}
else{
aInOutMap.Bind(aHole, aSolid);
aInOutMap.Bind (aHole, aSolid);
}
}
}//for (; aItDMISB.More(); aItDMISB.Next()) {
//
// 5. Map [Solid/Holes] -> aMSH
aItDMSS.Initialize(aInOutMap);
for (; aItDMSS.More(); aItDMSS.Next()) {
const TopoDS_Shape& aHole=aItDMSS.Key();
const TopoDS_Shape& aSolid=aItDMSS.Value();
//
// Add aHole to a map Solid/ListOfHoles [aMSH]
if (aInOutMap.IsBound(aHole)){
const TopoDS_Shape& aSolid=aInOutMap(aHole);
if (aMSH.IsBound(aSolid)) {
BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
aLH.Append(aHole);
@@ -558,41 +535,43 @@ void BOPAlgo_BuilderSolid::PerformAreas()
aLH.Append(aHole);
aMSH.Bind(aSolid, aLH);
}
//aBB.Add (aSolid, aHole);
}
}// for (; aShellIt.More(); aShellIt.Next()) {
//
// 6. Add aHoles to Solids
// 3. Add aHoles to Solids
aItMSH.Initialize(aMSH);
for (; aItMSH.More(); aItMSH.Next()) {
TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
//
const BOPCol_ListOfShape& aLH=aItMSH.Value();
aItLS.Initialize(aLH);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aItLS.Value();
aShellIt.Initialize(aLH);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aHole = aShellIt.Value();
aBB.Add (aSolid, aHole);
}
//
// update classifier
BRepClass3d_SolidClassifier& aSC=
myContext->SolidClassifier(aSolid);
BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
aSC.Load(aSolid);
//
}
//
// 7. These aNewSolids are draft solids that
// These aNewSolids are draft solids that
// do not contain any internal shapes
aItLS.Initialize(aNewSolids);
for ( ; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSx=aItLS.Value();
//
aShellIt.Initialize(aNewSolids);
for ( ; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aSx = aShellIt.Value();
myAreas.Append(aSx);
}
// Add holes that outside the solids to myAreas
aItLS.Initialize(aHoleShells);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aItLS.Value();
aShellIt.Initialize(aHoleShells);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aHole = aShellIt.Value();
if (!aInOutMap.IsBound(aHole)){
TopoDS_Solid aSolid;
//
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aHole);
//
@@ -604,7 +583,7 @@ void BOPAlgo_BuilderSolid::PerformAreas()
//function : PerformInternalShapes
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformInternalShapes()
void BOPAlgo_BuilderSolid::PerformInternalShapes()
{
myErrorStatus=0;
//
@@ -613,169 +592,95 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
return;
}
//
Standard_Integer k, aNbVFS, aNbSLF, aNbF, aNbA;
BRep_Builder aBB;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_MapOfShape aMFs;
BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
BOPCol_MapIteratorOfMapOfShape aItMF;
//
BOPCol_MapOfShape aMF, aMFP, aMFx;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
BOPCol_ListOfShape aLSI;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPDS_BoxBndTreeSelector aSelector;
BOPDS_BoxBndTree aBBTree;
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
BOPCol_DataMapOfIntegerShape aDMIS;
//
aNbA=myAreas.Extent();
//
// 1. Prepare tree filler
k = 0;
aItLS.Initialize(myLoopsInternal);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aShell=aItLS.Value();
// 1. All internal faces
aShellIt.Initialize(myLoopsInternal);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aShell=aShellIt.Value();
aIt.Initialize(aShell);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
const TopoDS_Shape& aF=aIt.Value();
aMF.Add(aF);
}
}
aNbFI=aMF.Extent();
//
if (aMFs.Add(aF)) {
if (aNbA) {
Bnd_Box aBox;
BRepBndLib::Add(aF, aBox);
aDMIS.Bind(k, aF);
aTreeFiller.Add(k++, aBox);
}
// 2 Process solids
aSolidIt.Initialize(myAreas);
for ( ; aSolidIt.More(); aSolidIt.Next()) {
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
//
TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
for (; anExpSol.More(); anExpSol.Next()) {
const TopoDS_Shape& aF = anExpSol.Current();
TopoDS_Shape aFF=aF;
//
aFF.Orientation(TopAbs_FORWARD);
aMFx.Add(aFF);
aFF.Orientation(TopAbs_REVERSED);
aMFx.Add(aFF);
}
aMEF.Clear();
BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
//
// 2.1 Separate faces to process aMFP
aMFP.Clear();
aItMF.Initialize(aMF);
for (; aItMF.More(); aItMF.Next()) {
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
if (!aMFx.Contains(aF)) {
if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
aMFP.Add(aF);
}
}
}
aMFx.Clear();
//
if (!aNbA) {
// 7b. "Rest" faces treatment
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
// 2.2 Make Internal Shells
aLSI.Clear();
MakeInternalShells(aMFP, aLSI);
//
MakeInternalShells(aMFs, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
// 2.3 Add them to aSolid
aShellIt.Initialize(aLSI);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aSI=aShellIt.Value();
aBB.Add (aSolid, aSI);
}
myAreas.Append(aSolid);
//
return; // =>
}//if (!aNbA) {
//
//2. fill tree filler
aTreeFiller.Fill();
//
// 3. Face/Solid candidates: aVFS
BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
BOPCol_MapOfShape aMFProcessed;
//
aItLS.Initialize(myAreas);
for (; aItLS.More(); aItLS.Next()) {
Bnd_Box aBox;
//
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
BRepBndLib::Add(aSolid, aBox);
//
aMFs.Clear();
aExp.Init(aSolid, TopAbs_FACE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aFs=aExp.Current();
aMFs.Add(aFs);
// 2.4 Remove faces aMFP from aMF
aItMF.Initialize(aMFP);
for (; aItMF.More(); aItMF.Next()) {
const TopoDS_Shape& aF=aItMF.Key();
aMF.Remove(aF);
}
//
aSelector.Clear();
aSelector.SetBox(aBox);
//
aNbF=aBBTree.Select(aSelector);
//
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
k=aItLI.Value();
const TopoDS_Face& aF = *(TopoDS_Face*)&aDMIS.Find(k);
if (aMFs.Contains(aF)) {
continue;
aNbFI=aMF.Extent();
if (!aNbFI) {
break;
}
//
gp_Pnt aP;
gp_Pnt2d aP2D;
//
BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
//
TopAbs_State aState=BOPTools_AlgoTools::ComputeState(aP, aSolid,
Precision::Confusion(),
myContext);
if (aState==TopAbs_IN) {
if (aMSLF.Contains(aSolid)) {
BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
aLF.Append(aF);
}
else {
BOPCol_ListOfShape aLF;
//
aLF.Append(aF);
aMSLF.Add(aSolid, aLF);
}
}
}
}// for (k=0; k < aNbVE; ++k) {
//
// 6. Update Solids by internal Faces
aNbSLF=aMSLF.Extent();
for (k=1; k <= aNbSLF; ++k) {
const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
//
const BOPCol_ListOfShape& aLF=aMSLF(k);
//
aMFs.Clear();
aItLS.Initialize(aLF);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aF=aItLS.Value();
aMFs.Add(aF);
aMFProcessed.Add(aF);
}
//
aLSI.Clear();
MakeInternalShells(aMFs, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
aBB.Add (*pSolid, aSI);
}
}
//
// 7. "Rest" faces treatment (if there are)
aMFs.Clear();
aNbVFS = aDMIS.Extent();
for (k=0; k < aNbVFS; ++k) {
const TopoDS_Face& aF=*(TopoDS_Face*)&aDMIS.Find(k);
if (!aMFProcessed.Contains(aF)) {
aMFs.Add(aF);
}
}
//
aNbFI=aMFs.Extent();
} //for ( ; aSolidIt.More(); aSolidIt.Next()) {
if (aNbFI) {
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
//
aLSI.Clear();
MakeInternalShells(aMFs, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
MakeInternalShells(aMF, aLSI);
aShellIt.Initialize(aLSI);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aSI=aShellIt.Value();
aBB.Add (aSolid, aSI);
}
myAreas.Append(aSolid);
}
}
//=======================================================================
//function : MakeInternalShells
//purpose :
@@ -793,9 +698,7 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF,
aItM.Initialize(theMF);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aF=aItM.Key();
BOPTools::MapShapesAndAncestors(aF,
TopAbs_EDGE, TopAbs_FACE,
aMEF);
BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
}
//
aItM.Initialize(theMF);
@@ -829,7 +732,6 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF,
}
}
}
aShell.Closed (BRep_Tool::IsClosed (aShell));
theShells.Append(aShell);
}
}
@@ -870,9 +772,7 @@ Standard_Boolean IsInside(const TopoDS_Shape& theS1,
BOPCol_IndexedMapOfShape aBounds;
BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
aState=BOPTools_AlgoTools::ComputeState(aF, *pS2,
Precision::Confusion(),
aBounds, theContext);
aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
}
return (aState==TopAbs_IN);
}
@@ -898,3 +798,42 @@ Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
}
return bRet;
}
//=======================================================================
//function : IsClosedShell
//purpose :
//=======================================================================
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
{
Standard_Integer aNbE;
Standard_Boolean bRet;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
//
BOPCol_MapOfShape aM;
//
bRet=Standard_False;
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
if (aE.Orientation()==TopAbs_INTERNAL) {
continue;
}
if (!aM.Add(aE)) {
aM.Remove(aE);
}
}
}
//
aNbE=aM.Extent();
if (!aNbE) {
bRet=!bRet;
}
return bRet;
}

View File

@@ -64,9 +64,6 @@
#include <BOPCol_ListOfInteger.hxx>
#include <BOPInt_Context.hxx>
#include <TCollection_CompareOfInteger.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <SortTools_QuickSortOfInteger.hxx>
static
Standard_Boolean IsClosedShell(const TopoDS_Shell& aSh);
@@ -303,17 +300,8 @@ void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts
aSelector.SetBox(aBoxS);
//
aNbFP=aBBTree.Select(aSelector);
if (aNbFP) {
//
const BOPCol_ListOfInteger& aLIFP=aSelector.Indices();
//sort indices
TColStd_Array1OfInteger anArray(1, aNbFP);
aItLI.Initialize(aLIFP);
for (k = 1; aItLI.More(); aItLI.Next(), ++k) {
nFP=aItLI.Value();
anArray(k) = nFP;
}
TCollection_CompareOfInteger comp;
SortTools_QuickSortOfInteger::Sort(anArray,comp);
//
// 2.7. Collect faces that are IN aSolid [ aLFIN ]
BOPCol_ListOfShape aLFP(aAlr1);
@@ -323,8 +311,9 @@ void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts
//
BOPTools::MapShapes(aSD, TopAbs_EDGE, aME);
//
for (k = 1; k <= aNbFP; ++k) {
nFP = anArray(k);
aItLI.Initialize(aLIFP);
for (; aItLI.More(); aItLI.Next()) {
nFP=aItLI.Value();
const BOPAlgo_ShapeBox& aSBF=aDMISB.Find(nFP);
const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
if (aMFDone.Contains(aFP)) {
@@ -365,7 +354,6 @@ void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts
}
}// for (; aItLI.More(); aItLI.Next()) {
//
}
// 2.8. Store the results in theInParts, theDraftSolids
aNbFIN=aLFIN.Extent();
if (aNbFIN || aNbLIF) {

View File

@@ -1,73 +0,0 @@
-- Created by: Peter KURNEV
-- Copyright (c) 1999-2014 OPEN CASCADE SAS
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
--
-- Alternatively, this file may be used under the terms of Open CASCADE
-- commercial license or contractual agreement.
class ShellSplitter from BOPAlgo
inherits Algo from BOPAlgo
---Purpose:
-- The class provides the splitting of the set of connected faces
-- on separate loops
uses
BaseAllocator from BOPCol,
Shape from TopoDS,
ListOfShape from BOPCol,
ConnexityBlock from BOPTools,
ListOfConnexityBlock from BOPTools
--raises
is
Create
returns ShellSplitter from BOPAlgo;
---C++: alias "Standard_EXPORT virtual ~BOPAlgo_ShellSplitter();"
---Purpose: empty constructor
Create(theAllocator: BaseAllocator from BOPCol)
returns ShellSplitter from BOPAlgo;
---Purpose: constructor
AddStartElement(me:out;
theS: Shape from TopoDS);
---Purpose: adds a face <theS> to process
StartElements(me)
returns ListOfShape from BOPCol;
---C++: return const &
---Purpose: return the faces to process
Perform(me:out)
is redefined;
---Purpose: performs the algorithm
Shells(me)
returns ListOfShape from BOPCol;
---C++: return const &
---Purpose: returns the loops
MakeConnexityBlocks(me:out)
is protected;
MakeShells (me:out)
is protected;
SplitBlock(myclass;
theCB:out ConnexityBlock from BOPTools);
fields
myStartShapes: ListOfShape from BOPCol is protected;
myShells: ListOfShape from BOPCol is protected;
myLCB : ListOfConnexityBlock from BOPTools is protected;
end ShellSplitter;

View File

@@ -1,612 +0,0 @@
// Created by: Peter KURNEV
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// File: BOPAlgo_ShellSplitter.cxx
// Created: Thu Jan 16 08:33:50 2014
// <pkv@PETREX>
#include <BOPAlgo_ShellSplitter.ixx>
//
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Edge.hxx>
#include <BRep_Builder.hxx>
#include <TopExp_Explorer.hxx>
//
#include <BOPCol_IndexedMapOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BOPCol_MapOfOrientedShape.hxx>
#include <BOPCol_NCVector.hxx>
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
//
#include <BOPInt_Context.hxx>
//
#include <BOPTools.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_CoupleOfShape.hxx>
//
static
void MakeShell(const BOPCol_ListOfShape& ,
TopoDS_Shell& );
//
static
void RefineShell(TopoDS_Shell& theShell);
//
static
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
//=======================================================================
//function :
//purpose :
//=======================================================================
BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter()
:
BOPAlgo_Algo(),
myStartShapes(myAllocator),
myShells(myAllocator),
myLCB(myAllocator)
{
}
//=======================================================================
//function :
//purpose :
//=======================================================================
BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter
(const Handle(NCollection_BaseAllocator)& theAllocator)
:
BOPAlgo_Algo(theAllocator),
myStartShapes(theAllocator),
myShells(theAllocator),
myLCB(myAllocator)
{
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
BOPAlgo_ShellSplitter::~BOPAlgo_ShellSplitter()
{
}
//=======================================================================
//function : AddStartElement
//purpose :
//=======================================================================
void BOPAlgo_ShellSplitter::AddStartElement(const TopoDS_Shape& aE)
{
myStartShapes.Append(aE);
}
//=======================================================================
//function : StartElements
//purpose :
//=======================================================================
const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::StartElements()const
{
return myStartShapes;
}
//=======================================================================
//function : Loops
//purpose :
//=======================================================================
const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::Shells()const
{
return myShells;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BOPAlgo_ShellSplitter::Perform()
{
myErrorStatus=0;
//
MakeConnexityBlocks();
if (myErrorStatus) {
return;
}
//
MakeShells();
}
//=======================================================================
//function : MakeConnexityBlocks
//purpose :
//=======================================================================
void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
{
Standard_Boolean bRegular;
Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
TopoDS_Shape aFR;
TopExp_Explorer aExpF;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator);
BOPCol_IndexedMapOfShape aMEP(100, myAllocator);
BOPCol_IndexedMapOfShape aMFC(100, myAllocator);
BOPCol_MapOfShape aMER(100, myAllocator);
BOPCol_MapOfShape aMFP(100, myAllocator);
BOPCol_IndexedMapOfShape aMEAdd(100, myAllocator);
BOPCol_MapOfShape aMES(100, myAllocator);
BOPCol_ListIteratorOfListOfShape aIt;
//
myErrorStatus=0;
//
myLCB.Clear();
//
const BOPCol_ListOfShape& aLSE=myStartShapes;
aIt.Initialize(aLSE);
for (i=1; aIt.More(); aIt.Next(), ++i) {
const TopoDS_Shape& aSE=aIt.Value();
if (!aMEP.Contains(aSE)) {
aMEP.Add(aSE);
BOPTools::MapShapesAndAncestors(aSE,
TopAbs_EDGE,
TopAbs_FACE,
aMEF);
}
else {
aMER.Add(aSE);
}
}
//
// 2
aNbE=aMEF.Extent();
for (i=1; i<=aNbE; ++i) {
aNbES=aMES.Extent();
if (aNbES==aNbE) {
break;
}
//
const TopoDS_Shape& aE=aMEF.FindKey(i);
//
if (!aMES.Add(aE)) {
continue;
}
// aMES - globally processed edges
//
//------------------------------------- goal: aMEC
aMFC.Clear(); // aMEC - edges of CB
aMEP.Clear(); // aMVP - edges to process right now
aMEAdd.Clear(); // aMVAdd edges to process on next step of for(;;) {
//
aMEP.Add(aE);
//
for(;;) {
aNbEP=aMEP.Extent();
for (k=1; k<=aNbEP; ++k) {
const TopoDS_Shape& aEP=aMEP(k);
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP);
aIt.Initialize(aLF);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (aMFC.Add(aF)) {
aExpF.Init(aF, TopAbs_EDGE);
for (; aExpF.More(); aExpF.Next()) {
const TopoDS_Shape& aEF=aExpF.Current();
if (aMES.Add(aEF)) {
aMEAdd.Add(aEF);
}
}
}
}
}
//
aNbEP=aMEAdd.Extent();
if (!aNbEP) {
break; // from for(;;) {
}
//
aMEP.Clear();
//
for (k=1; k<=aNbEP; ++k) {
const TopoDS_Shape& aEF=aMEAdd(k);
aMEP.Add(aEF);
}
aMEAdd.Clear();
}// for(;;) {
//
//-------------------------------------
BOPTools_ConnexityBlock aCB(myAllocator);
//
BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator);
//
bRegular=Standard_True;
aNbCB = aMFC.Extent();
for (j=1; j<=aNbCB; ++j) {
aFR = aMFC(j);
//
if (aMER.Contains(aFR)) {
aFR.Orientation(TopAbs_FORWARD);
aLECB.Append(aFR);
aFR.Orientation(TopAbs_REVERSED);
aLECB.Append(aFR);
bRegular=Standard_False;
}
else {
aLECB.Append(aFR);
}
//
if (bRegular) {
BOPTools::MapShapesAndAncestors(aFR,
TopAbs_EDGE,
TopAbs_FACE,
aMEFR);
}
}
//
if (bRegular) {
Standard_Integer aNbER, aNbFR;
//
aNbER=aMEFR.Extent();
for (k=1; k<=aNbER; ++k) {
const BOPCol_ListOfShape& aLFR=aMEFR(k);
aNbFR=aLFR.Extent();
if (aNbFR>2) {
bRegular=!bRegular;
break;
}
}
}
//
aCB.SetRegular(bRegular);
myLCB.Append(aCB);
}
}
//=======================================================================
//function : SplitBlock
//purpose :
//=======================================================================
void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
{
Standard_Integer aNbLF, aNbOff, aNbFP;
Standard_Integer i;
TopAbs_Orientation anOr;
TopoDS_Edge aEL;
BRep_Builder aBB;
TopoDS_Iterator aItS;
TopExp_Explorer aExp;
BOPCol_ListIteratorOfListOfShape aItF;
BOPTools_CoupleOfShape aCSOff;
BOPCol_MapOfOrientedShape AddedFacesMap;
BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
//
Handle (BOPInt_Context) aContext=new BOPInt_Context;
//
const BOPCol_ListOfShape& myShapes=aCB.Shapes();
//
BOPCol_ListOfShape& myLoops=aCB.ChangeLoops();
myLoops.Clear();
//
// 1. Shells Usual
aItF.Initialize (myShapes);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Shape& aFF = aItF.Value();
BOPTools::MapShapesAndAncestors (aFF,
TopAbs_EDGE,
TopAbs_FACE,
aEFMap);
}
//
aItF.Initialize (myShapes);
for (i=1; aItF.More(); aItF.Next(), ++i) {
const TopoDS_Shape& aFF = aItF.Value();
if (!AddedFacesMap.Add(aFF)) {
continue;
}
//
// make a new shell
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
aBB.Add(aShell, aFF);
//
aMEFP.Clear();
BOPTools::MapShapesAndAncestors(aFF,
TopAbs_EDGE,
TopAbs_FACE,
aMEFP);
//
// loop on faces added to Shell;
// add their neighbor faces to Shell and so on
aItS.Initialize (aShell);
for (; aItS.More(); aItS.Next()) {
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
//
// loop on edges of aF; find a good neighbor face of aF by aE
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
//
//1
if (aMEFP.Contains(aE)) {
const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
aNbFP=aLFP.Extent();
if (aNbFP>1) {
continue;
}
}
//2
anOr=aE.Orientation();
if (anOr==TopAbs_INTERNAL) {
continue;
}
//3
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
// candidate faces list
const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
aNbLF=aLF.Extent();
if (!aNbLF) {
continue;
}
//
// try to select one of neighbors
// check if a face already added to Shell shares E
Standard_Boolean bFound;
BOPCol_ListIteratorOfListOfShape aItLF;
BOPTools_ListOfCoupleOfShape aLCSOff;
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
if (aF.IsSame(aFL)) {
continue;
}
if (AddedFacesMap.Contains(aFL)){
continue;
}
//
bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
if (!bFound) {
continue;
}
//
aCSOff.SetShape1(aEL);
aCSOff.SetShape2(aFL);
aLCSOff.Append(aCSOff);
}//for (; aItLF.More(); aItLF.Next()) {
//
aNbOff=aLCSOff.Extent();
if (!aNbOff){
continue;
}
//
TopoDS_Face aSelF;
if (aNbOff==1) {
aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
}
else if (aNbOff>1){
BOPTools_AlgoTools::GetFaceOff(aE,
aF,
aLCSOff,
aSelF,
aContext);
}
//
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
aBB.Add(aShell, aSelF);
BOPTools::MapShapesAndAncestors(aSelF,
TopAbs_EDGE,
TopAbs_FACE,
aMEFP);
}
} // for (; aExp.More(); aExp.Next()) {
} // for (; aItS.More(); aItS.Next()) {
//
if (IsClosedShell(aShell)) {
aShell.Closed (Standard_True);
myLoops.Append(aShell);
}
else {
RefineShell(aShell);
if (IsClosedShell(aShell)) {
aShell.Closed (Standard_True);
myLoops.Append(aShell);
}
}
} // for (; aItF.More(); aItF.Next()) {
}
//=======================================================================
//function : RefineShell
//purpose :
//=======================================================================
void RefineShell(TopoDS_Shell& theShell)
{
TopoDS_Iterator aIt;
//
aIt.Initialize(theShell);
if(!aIt.More()) {
return;
}
//
Standard_Integer i, aNbMEF, aNbF;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
TopoDS_Builder aBB;
TopExp_Explorer aExp;
BOPCol_MapOfShape aMEStop, aMFB;
BOPCol_MapIteratorOfMapOfShape aItM;
BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
BOPCol_ListOfShape aLFP, aLFP1;
//
// Branch points
BOPTools::MapShapesAndAncestors (theShell,
TopAbs_EDGE,
TopAbs_FACE,
aMEF);
aNbMEF=aMEF.Extent();
for (i=1; i<=aNbMEF; ++i) {
const TopoDS_Shape& aE=aMEF.FindKey(i);
const BOPCol_ListOfShape& aLF=aMEF.FindFromIndex(i);
aNbF=aLF.Extent();
if (aNbF>2) {
aMEStop.Add(aE);
}
}
//
if (aMEStop.IsEmpty()) {
return;
}
//
// The first Face
const TopoDS_Shape& aF1=aIt.Value();
aMFB.Add(aF1);
aLFP.Append(aF1);
//
// Trying to reach the branch point
for (;;) {
aItLFP.Initialize(aLFP);
for (; aItLFP.More(); aItLFP.Next()) {
const TopoDS_Shape& aFP=aItLFP.Value();
//
aExp.Init(aFP, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (aMEStop.Contains(aE)) {
continue;
}
//
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
if (aFP1.IsSame(aFP)) {
continue;
}
if (aMFB.Contains(aFP1)) {
continue;
}
aMFB.Add(aFP1);
aLFP1.Append(aFP1);
}// for (; aItLF.More(); aItLF.Next()) {
}// for (; aExp.More(); aExp.Next()) {
}// for (; aItLFP.More(); aItLFP.Next()) {
//
//
if (aLFP1.IsEmpty()) {
break;
}
//
aLFP.Clear();
aItLF.Initialize(aLFP1);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
aLFP.Append(aFP1);
}
aLFP1.Clear();
}// for (;;) {
//
// Remove all faces before the branch point
aItM.Initialize(aMFB);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aFB=aItM.Value();
aBB.Remove(theShell, aFB);
}
}
//=======================================================================
//function : MakeShells
//purpose :
//=======================================================================
void BOPAlgo_ShellSplitter::MakeShells()
{
Standard_Boolean bIsRegular;
BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
BOPCol_ListIteratorOfListOfShape aIt;
//
myErrorStatus=0;
myShells.Clear();
//
aItCB.Initialize(myLCB);
for (; aItCB.More(); aItCB.Next()) {
BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
bIsRegular=aCB.IsRegular();
if (bIsRegular) {
TopoDS_Shell aShell;
//
const BOPCol_ListOfShape& aLF=aCB.Shapes();
MakeShell(aLF, aShell);
aShell.Closed(Standard_True);
myShells.Append(aShell);
}
else {
SplitBlock(aCB);
const BOPCol_ListOfShape& aLS=aCB.Loops();
aIt.Initialize(aLS);
for (; aIt.More(); aIt.Next()) {
TopoDS_Shape& aShell=aIt.ChangeValue();
aShell.Closed(Standard_True);
myShells.Append(aShell);
}
}
}
}
//=======================================================================
//function : MakeShell
//purpose :
//=======================================================================
void MakeShell(const BOPCol_ListOfShape& aLS,
TopoDS_Shell& aShell)
{
BRep_Builder aBB;
BOPCol_ListIteratorOfListOfShape aIt;
//
aBB.MakeShell(aShell);
//
aIt.Initialize(aLS);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
aBB.Add(aShell, aF);
}
}
//=======================================================================
//function : IsClosedShell
//purpose :
//=======================================================================
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
{
Standard_Integer aNbE;
Standard_Boolean bRet;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
BOPCol_MapOfShape aM;
//
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
if (aE.Orientation()==TopAbs_INTERNAL) {
continue;
}
//
if (!aM.Add(aE)) {
aM.Remove(aE);
}
}
}
//
aNbE = aM.Extent();
bRet = (aNbE > 0) ? Standard_False : Standard_True;
return bRet;
}

View File

@@ -1,342 +0,0 @@
#include <BRepCheck_SurfNormAnalyzer.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <Geom_Surface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <Adaptor3d_TopolTool.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <gp_VectorWithNullMagnitude.hxx>
static Standard_Real AdjustExtr(const Adaptor3d_Surface& S,
const Standard_Real UMin,
const Standard_Real UMax,
const Standard_Real VMin,
const Standard_Real VMax,
const Standard_Real Extr0,
const Standard_Real Tol,
Standard_Real& uextr,
Standard_Real& vextr );
//=======================================================================
//function : BRepCheck_Analyzer
//purpose :
//=======================================================================
BRepCheck_SurfNormAnalyzer::BRepCheck_SurfNormAnalyzer ():
myAngTol(0.01)
{
}
//=======================================================================
//function : BRepCheck_Analyzer
//purpose :
//=======================================================================
BRepCheck_SurfNormAnalyzer::BRepCheck_SurfNormAnalyzer
(const TopoDS_Shape& theS,
const Standard_Real theAngTol):
myShape(theS), myAngTol(theAngTol)
{
}
//=======================================================================
//function : IsValid
//purpose :
//=======================================================================
Standard_Boolean BRepCheck_SurfNormAnalyzer::IsValid()
{
TopLoc_Location anL;
myBadFaces.Clear();
Standard_Real umin, umax, vmin, vmax;
TopExp_Explorer anEx(myShape, TopAbs_FACE);
for(; anEx.More(); anEx.Next())
{
TopoDS_Face aF = TopoDS::Face(anEx.Current());
BRepTools::UVBounds(aF, umin, umax, vmin, vmax);
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aF, anL);
if(IsProblemSurf(aSurf, umin, umax, vmin, vmax, myAngTol))
{
myBadFaces.Append(aF);
}
}
return myBadFaces.IsEmpty();
}
//=======================================================================
//function : BadFaces
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepCheck_SurfNormAnalyzer::BadFaces() const
{
return myBadFaces;
}
//=======================================================================
//function : SetShape
//purpose :
//=======================================================================
void BRepCheck_SurfNormAnalyzer::SetShape(const TopoDS_Shape& theShape)
{
myBadFaces.Clear();
myShape = theShape;
}
//=======================================================================
//function : SetTolerance
//purpose :
//=======================================================================
void BRepCheck_SurfNormAnalyzer::SetTolerance(const Standard_Real theAngTol)
{
myBadFaces.Clear();
myAngTol = theAngTol;
}
//=======================================================================
//function : GetShape
//purpose :
//=======================================================================
const TopoDS_Shape& BRepCheck_SurfNormAnalyzer::GetShape() const
{
return myShape;
}
//=======================================================================
//function : GetTolerance
//purpose :
//=======================================================================
Standard_Real BRepCheck_SurfNormAnalyzer::GetTolerance() const
{
return myAngTol;
}
//=======================================================================
//function : IsProblemSurf
//purpose :
//=======================================================================
Standard_Boolean
BRepCheck_SurfNormAnalyzer::IsProblemSurf(const Handle_Geom_Surface& theSurf,
const Standard_Real theUMin,
const Standard_Real theUMax,
const Standard_Real theVMin,
const Standard_Real theVMax,
const Standard_Real theAngTol)
{
Standard_Boolean aStatus = Standard_False;
GeomAdaptor_Surface aGAS(theSurf, theUMin, theUMax, theVMin, theVMax);
GeomAbs_SurfaceType aSType = aGAS.GetType();
//
if(aSType <= GeomAbs_Torus)
{
return aStatus;
}
//
Handle(GeomAdaptor_HSurface) aGAHS = new GeomAdaptor_HSurface(aGAS);
Handle(Adaptor3d_TopolTool) aTT = new Adaptor3d_TopolTool(aGAHS);
if(aTT->DomainIsInfinite())
{
return aStatus;
}
//
Standard_Real aDefl = 0.1; //the same as for intersection default
Standard_Integer aNbMinU = 10, aNbMinV = 10;
aTT->SamplePnts(aDefl, aNbMinU, aNbMinV);
Standard_Integer aNbU = aTT->NbSamplesU();
Standard_Integer aNbV = aTT->NbSamplesV();
TColStd_Array1OfReal anUPars(1, aNbU), aVPars(1, aNbV);
aTT->UParameters(anUPars);
aTT->VParameters(aVPars);
//
gp_Pnt aP;
gp_Vec aDU, aDV;
Standard_Real u, v, ang;
TColStd_Array2OfReal aTabN(1, aNbU, 1, aNbV);
Standard_Integer i, j;
//Check singular point on boundary
for(j = 1; j <= aNbV; j += aNbV-1)
{
aP = theSurf->Value(anUPars(1), aVPars(j));
Standard_Real length = 0.;
for(i = 2; i <= aNbU; ++i)
{
gp_Pnt aPcur = theSurf->Value(anUPars(i), aVPars(j));
length += aPcur.Distance(aP);
if(length > Precision::Confusion())
{
break;
}
aP = aPcur;
}
if(length <= Precision::Confusion())
{
if(j == 1)
{
aVPars(j) += (aVPars(2)-aVPars(1)) / 10.;
}
else
{
aVPars(aNbV) -= (aVPars(aNbV)-aVPars(aNbV-1)) / 10.;
}
}
}
for(j = 1; j <= aNbU; j += aNbU-1)
{
aP = theSurf->Value(anUPars(j), aVPars(1));
Standard_Real length = 0.;
for(i = 2; i <= aNbV; ++i)
{
gp_Pnt aPcur = theSurf->Value(anUPars(j), aVPars(i));
length += aPcur.Distance(aP);
if(length > Precision::Confusion())
{
break;
}
aP = aPcur;
}
if(length <= Precision::Confusion())
{
if(j == 1)
{
anUPars(j) += (anUPars(2)-anUPars(1)) / 10.;
}
else
{
anUPars(aNbU) -= (anUPars(aNbU)-anUPars(aNbU-1)) / 10.;
}
}
}
//
for(i = 1; i <= aNbU; ++i)
{
u = anUPars(i);
for(j = 1; j <= aNbV; ++j)
{
v = aVPars(j);
theSurf->D1(u, v, aP, aDU, aDV);
try
{
ang = aDU.Angle(aDV);
if(ang > M_PI/2.)
{
ang = M_PI - ang;
}
}
catch (gp_VectorWithNullMagnitude)
{
ang = 0.;
}
aTabN(i, j) = ang;
}
}
//
Standard_Real min = RealLast();
Standard_Integer imin = 0, jmin = 0;
for(i = 1; i <= aNbU; ++i)
{
for(j = 1; j <= aNbV; ++j)
{
if(aTabN(i, j) < theAngTol)
{
return Standard_True;
}
else
{
if(aTabN(i, j) < min)
{
min = aTabN(i, j);
imin = i;
jmin = j;
}
}
}
}
//
Standard_Real umin = anUPars(Max(1, imin-1));
Standard_Real umax = anUPars(Min(aNbU, imin+1));
Standard_Real vmin = aVPars(Max(1, jmin-1));
Standard_Real vmax = aVPars(Min(aNbV, jmin+1));
//
Standard_Real min0 = min, uextr = anUPars(imin), vextr = aVPars(jmin);
min = AdjustExtr(aGAS, umin, umax, vmin, vmax,
min0, theAngTol / 10., uextr, vextr );
if(min < theAngTol)
{
aStatus = Standard_True;
}
return aStatus;
}
Standard_Real AdjustExtr(const Adaptor3d_Surface& S,
const Standard_Real UMin,
const Standard_Real UMax,
const Standard_Real VMin,
const Standard_Real VMax,
const Standard_Real Extr0,
const Standard_Real Tol,
Standard_Real& uextr,
Standard_Real& vextr )
{
Standard_Integer Nu = 5, Nv = 5;
gp_Pnt P;
gp_Vec DU, DV;
Standard_Integer i, j;
Standard_Real du = (UMax-UMin)/(Nu-1);
Standard_Real dv = (VMax-VMin)/(Nv-1);
Standard_Real extr = Extr0;
Standard_Real u, v, ang;
for (i = 1, u = UMin; i <= Nu; i++, u += du){
for (j = 1, v = VMin;j <= Nv; j++, v += dv){
S.D1(u,v,P,DU,DV);
try
{
ang = DU.Angle(DV);
if(ang > M_PI/2.)
{
ang = M_PI - ang;
}
}
catch (gp_VectorWithNullMagnitude)
{
ang = 0.;
}
//
if(extr > ang)
{
extr = ang;
uextr = u;
vextr = v;
}
}
}
if(Abs(extr - Extr0) > Tol)
{
Standard_Real umin, umax, vmin, vmax;
umin = Max(UMin, uextr - du);
umax = Min(UMax, uextr + du);
vmin = Max(VMin, vextr - dv);
vmax = Min(VMax, vextr + dv);
Standard_Real extr0 = extr;
extr = AdjustExtr(S, umin, umax, vmin, vmax,
extr0, Tol, uextr, vextr);
}
return extr;
}

View File

@@ -1,84 +0,0 @@
#ifndef _BRepCheck_SurfNormAnalyzer_HeaderFile
#define _BRepCheck_SurfNormAnalyzer_HeaderFile
#ifndef _Standard_HeaderFile
#include <Standard.hxx>
#endif
#ifndef _Standard_DefineAlloc_HeaderFile
#include <Standard_DefineAlloc.hxx>
#endif
#ifndef _Standard_Macro_HeaderFile
#include <Standard_Macro.hxx>
#endif
#ifndef _TopoDS_Shape_HeaderFile
#include <TopoDS_Shape.hxx>
#endif
#ifndef _Standard_Boolean_HeaderFile
#include <Standard_Boolean.hxx>
#endif
#ifndef _TopAbs_ShapeEnum_HeaderFile
#include <TopAbs_ShapeEnum.hxx>
#endif
#include <TopTools_ListOfShape.hxx>
class Handle_Geom_Surface;
//! A class to check the problems with calculations<br>
//! of normals of face surfaces when dS/du and dS/dv are almost parallel:
//! normal to surface is calculated as N = dS/du^dS/dv and when<br>
//! dS/du || dS/dv N is poor defined. It can cause problems in intersection<br>
//! and other algoritms.<br>
//! This class diagnoses whether the area on the surface where angle between dS/du<br>
//! and dS/dv less then given angular tolerance. <br>
class BRepCheck_SurfNormAnalyzer {
public:
DEFINE_STANDARD_ALLOC
//
Standard_EXPORT BRepCheck_SurfNormAnalyzer();
Standard_EXPORT BRepCheck_SurfNormAnalyzer(const TopoDS_Shape& theS, const Standard_Real theAngTol);
//
Standard_EXPORT void SetShape(const TopoDS_Shape& theS);
Standard_EXPORT void SetTolerance(const Standard_Real theAngTol);
//
Standard_EXPORT Standard_Boolean IsValid();
//
Standard_EXPORT const TopoDS_Shape& GetShape() const;
Standard_EXPORT Standard_Real GetTolerance() const;
//
Standard_EXPORT const TopTools_ListOfShape& BadFaces() const;
//
Standard_EXPORT static Standard_Boolean
IsProblemSurf(const Handle_Geom_Surface& theSurf,
const Standard_Real theUMin,
const Standard_Real theUMax,
const Standard_Real theVMin,
const Standard_Real theVMax,
const Standard_Real theAngTol);
protected:
private:
TopoDS_Shape myShape;
TopTools_ListOfShape myBadFaces;
Standard_Real myAngTol;
};
#endif

View File

@@ -1,2 +0,0 @@
BRepCheck_SurfNormAnalyzer.hxx
BRepCheck_SurfNormAnalyzer.cxx

View File

@@ -5,8 +5,8 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
@@ -287,11 +287,7 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
// Put all poles for bezier
Handle(Geom_BezierCurve) GC = c.Bezier();
Standard_Integer iNbPol = GC->NbPoles();
Standard_Real tf = GC->FirstParameter();
Standard_Real tl = GC->LastParameter();
Standard_Real r = (dfUl - dfUf) / (tl - tf);
r *= iNbPol;
if ( iNbPol < 2 || r < 1.)
if ( iNbPol < 2)
// Degenerate
continue;
else
@@ -322,36 +318,20 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
// Put all poles for bspline
Handle(Geom_BSplineCurve) GC = c.BSpline();
Standard_Integer iNbPol = GC->NbPoles();
Standard_Real tf = GC->FirstParameter();
Standard_Real tl = GC->LastParameter();
Standard_Real r = (dfUl - dfUf) / (tl - tf);
r *= iNbPol;
if ( iNbPol < 2 || r < 1.)
if ( iNbPol < 2)
// Degenerate
continue;
else
{
const Standard_Integer aNbPolMax = 200;
Standard_Integer incr = 1;
if(iNbPol > aNbPolMax)
{
Standard_Integer nb = iNbPol;
while(nb > aNbPolMax)
{
incr++;
nb = (iNbPol-1) / incr;
}
}
Handle(TColgp_HArray1OfPnt) aPoles = new (TColgp_HArray1OfPnt) (1, iNbPol);
GC->Poles(aPoles->ChangeArray1());
gp_Pnt aPolePrev = aPoles->Value(1), aPoleNext;
Standard_Real dfDistPrev = 0., dfDistNext;
Standard_Integer iPol;
for (iPol = 1; iPol <= iNbPol; iPol += incr)
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
{
if (iPol <= iNbPol - incr)
if (iPol<iNbPol)
{
aPoleNext = aPoles->Value(iPol+incr);
aPoleNext = aPoles->Value(iPol+1);
dfDistNext = aPolePrev.Distance(aPoleNext);
}
else
@@ -470,8 +450,7 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
if (!isSolved || myTolerance < dfDist) {
gp_Pnt aFirstPnt=aPoints(1);
for (iPoint=2; iPoint<=aPoints.Length(); iPoint++) {
const gp_Pnt& aNextPnt = aPoints(iPoint);
gp_Vec aDir(aFirstPnt, aNextPnt);
gp_Vec aDir(aFirstPnt,aPoints(iPoint));
Standard_Real dfSide=aDir.Magnitude();
if (dfSide<myTolerance) {
continue; // degeneration
@@ -558,4 +537,3 @@ TopLoc_Location BRepLib_FindSurface::Location() const
return myLocation;
}

View File

@@ -23,7 +23,6 @@
#include <BRepCheck_Analyzer.hxx>
#include <BRepCheck_Result.hxx>
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
#include <BRepCheck_SurfNormAnalyzer.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
@@ -244,60 +243,6 @@ static void Print(Standard_OStream& OS,
}
//
//=======================================================================
//function : checknorm
//purpose : Checks the normals of faces
//=======================================================================
static Standard_Integer checknorm(Draw_Interpretor& di,
Standard_Integer narg, const char** a)
{
if (narg < 3) {
return 1;
}
Standard_Real tol = 1.e-2;
TopoDS_Shape S = DBRep::Get(a[2]);
if(S.IsNull())
{
di << "Null shape \n";
return 1;
}
TopExp_Explorer anExp(S, TopAbs_FACE);
if(!anExp.More())
{
di << "There are no faces in shape /n";
return 1;
}
//
if(narg > 3)
{
tol = atof(a[3]);
}
//
BRepCheck_SurfNormAnalyzer aNormChecker(S, tol);
if(aNormChecker.IsValid())
{
di << "All faces seem to be valid \n" ;
return 0;
}
const TopTools_ListOfShape& aBadFaces = aNormChecker.BadFaces();
//
di << " number of problematic faces : " << aBadFaces.Extent() << "\n";
//
char Name[32];
Standard_Integer ipp=0;
TopTools_ListIteratorOfListOfShape itf;
for (itf.Initialize(aBadFaces); itf.More(); itf.Next()) {
ipp++;
Sprintf(Name,"%s_%d",a[1], ipp);
DBRep::Set(Name, itf.Value());
di << Name << " " ;
}
di << "\n";
return 0;
}
//=======================================================================
//function : computetolerance
//purpose :
@@ -1732,11 +1677,5 @@ theCommands.Add("listfuseedge",
"listfuseedge shape",
__FILE__,
listfuseedge,g);
theCommands.Add("checknorm",
"checknorm name shape tol",
__FILE__,
checknorm,g);
}

View File

@@ -66,7 +66,7 @@ GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
//=======================================================================
IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
const Standard_Real aTol)
:
:
Tol(aTol),
done(Standard_False),
nbpnt(0),
@@ -95,7 +95,7 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
Standard_Boolean bFlag;
//
{
Standard_Real dU, dV, dA, dB, aTresh;
Standard_Real dU, dV, dA, dB, aR, aTresh;
bFlag=Standard_True;
//
aTresh=100.;
@@ -108,9 +108,15 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
dB=dU;
}
//
if (dB < Precision::PConfusion() || dA > dB * aTresh) {
aR=dA/dB;
if (dB<Precision::PConfusion()) {
bFlag=!bFlag;
}
else {
if (aR>aTresh) {
bFlag=!bFlag;
}
}
}
//
if (bFlag) {

View File

@@ -890,6 +890,76 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
wline->AddVertex(ptfin);
wline->SetLastPoint(wline->NbVertex());
}
if(wline->NbPnts() < 40)
{
Standard_Boolean hasBeenAdded = iwalk.SeekAdditionalPoints(Surf1, Surf2, 40, j);
if (!reversed)
IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang, hasBeenAdded);
else
IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang, hasBeenAdded);
if(hasBeenAdded)
{
const Standard_Real aTol = Precision::Confusion()*Precision::Confusion();
Standard_Real aDecrParam = 0.0;
Standard_Integer aNbVert = wline->NbVertex();
for (Standard_Integer aV = 2; aV <= aNbVert; aV++)
{
IntPatch_Point aVert = wline->Vertex(aV);
const gp_Pnt aP(aVert.Value()), aP1(wline->Vertex(aV-1).Value());
if(aV == aNbVert)
{
if(aP.SquareDistance(aP1) <= aTol)
{
wline->RemoveVertex(aV-1);
}
break;
}
else
{
aVert.SetParameter(aVert.ParameterOnLine() - aDecrParam);
wline->RemoveVertex(aV);
wline->InsertVertexBefore(aV, aVert);
}
const gp_Pnt aP2(wline->Vertex(aV+1).Value());
if(aP.SquareDistance(aP1) <= aTol)
{
wline->RemoveVertex(aV);
}
else if(aP.SquareDistance(aP2) <= aTol)
{
wline->RemoveVertex(aV);
aDecrParam++;
aV--;
aNbVert = wline->NbVertex();
}
aNbVert = wline->NbVertex();
}
}
if (wline->HasLastPoint())
{
wline->SetLastPoint(wline->NbVertex());
wline->LastPoint(indlast);
}
}
else
{
if (!reversed)
IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
else
IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
}
//
// Il faut traiter les points de passage.
slin.Append(wline);
@@ -1252,10 +1322,18 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
// on traite les restrictions de la surface implicite
for (i=1; i<=slin.Length(); i++)
{
Handle(IntPatch_Line)& aL = slin(i);
const Handle(IntPatch_WLine)& wline = Handle(IntPatch_WLine)::DownCast(aL);
if(!wline.IsNull())
{//It was processed above
continue;
}
if (!reversed)
IntPatch_RstInt::PutVertexOnLine(slin(i),Surf1,D1,Surf2,Standard_True,TolTang);
IntPatch_RstInt::PutVertexOnLine(aL,Surf1,D1,Surf2,Standard_True,TolTang, 1);
else
IntPatch_RstInt::PutVertexOnLine(slin(i),Surf2,D2,Surf1,Standard_False,TolTang);
IntPatch_RstInt::PutVertexOnLine(aL,Surf2,D2,Surf1,Standard_False,TolTang, 1);
}
empt = (slin.Length() == 0 && spnt.Length() == 0);
done = Standard_True;
@@ -1287,7 +1365,7 @@ static Handle(IntSurf_LineOn2S) VSplitLine(Handle(IntSurf_LineOn2S)& Line,
Standard_Boolean IsReversed,
Handle(Adaptor3d_HSurface)& QSurf,
Handle(IntSurf_LineOn2S)& Vertices)
{
{
Handle(IntSurf_LineOn2S) line = new IntSurf_LineOn2S();
Standard_Real VF = QSurf->FirstVParameter();
@@ -1403,7 +1481,7 @@ static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_WLine)& WLine,
const Standard_Real TOL3D,
const Standard_Real TOL2D)
{
// Standard_Real TOL3D = 1.e-12, TOL2D = 1.e-8;
// Standard_Real TOL3D = 1.e-12, TOL2D = 1.e-8;
Handle(IntSurf_LineOn2S) vertices = new IntSurf_LineOn2S();
@@ -1742,11 +1820,11 @@ static Standard_Boolean InsertSeamVertices(Handle(IntSurf_LineOn2S)& Line,
break;
}
else {
// Line->InsertBefore(ip,Line->Value(ipn));
// Line->RemovePoint(ip+2);
// result = Standard_True;
// cout << "swap vertex " << endl;
// break;
// Line->InsertBefore(ip,Line->Value(ipn));
// Line->RemovePoint(ip+2);
// result = Standard_True;
// cout << "swap vertex " << endl;
// break;
}
}
}
@@ -2391,7 +2469,7 @@ void DecomposeResult(Handle(IntPatch_Line)& Line,
AnV1=V1;
}
IntSurf_PntOn2S aVF,aVL;
IntSurf_PntOn2S aVF, aVL;
Standard_Boolean addVF = Standard_False, addVL = Standard_False;
VerifyVertices(sline,IsReversed,vline,TOL2DS,ArcTol,PDomain,aVF,addVF,aVL,addVL);
@@ -2461,22 +2539,22 @@ void DecomposeResult(Handle(IntPatch_Line)& Line,
sline = new IntSurf_LineOn2S();
goto nextline;
}
}
}
/*
// <-A
{
Standard_Integer aNbPnts;
Standard_Real aU1,aV1,aU2,aV2;
gp_Pnt aPx;
//
aNbPnts=thelin->NbPoints();
printf(" WLine: aNbPnts=%d\n", aNbPnts);
for(i=1; i <= aNbPnts; ++i) {
const IntSurf_PntOn2S& aPoint = thelin->Value(i);
aPx=aPoint.Value();
aPoint.Parameters(aU1, aV1, aU2, aV2);
printf(" point %d %lf %lf %lf %lf %lf %lf %lf\n",
i, aPx.X(), aPx.Y(), aPx.Z(), aU1, aV1, aU2, aV2);
}
}
{
Standard_Integer aNbPnts;
Standard_Real aU1,aV1,aU2,aV2;
gp_Pnt aPx;
//
aNbPnts=thelin->NbPoints();
printf(" WLine: aNbPnts=%d\n", aNbPnts);
for(i=1; i <= aNbPnts; ++i) {
const IntSurf_PntOn2S& aPoint = thelin->Value(i);
aPx=aPoint.Value();
aPoint.Parameters(aU1, aV1, aU2, aV2);
printf(" point %d %lf %lf %lf %lf %lf %lf %lf\n",
i, aPx.X(), aPx.Y(), aPx.Z(), aU1, aV1, aU2, aV2);
}
}
*/

View File

@@ -309,6 +309,18 @@ is
---C++: return const&
returns HCurve2d from Adaptor2d;
ClearVertexes(me: mutable)
is static;
RemoveVertex(me: mutable;
theIndex : Integer from Standard)
is static;
InsertVertexBefore(me: mutable;
theIndex : Integer from Standard;
thePnt : Point from IntPatch)
is static;
Dump(me)
is static;

View File

@@ -622,7 +622,17 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol,
RecadreMemePeriode(POn2S,curv->Value(nbponline),U1Period(),V1Period(),U2Period(),V2Period());
curv->Add(POn2S);
}
else {
else if(hasBeenAdded)
{
RecadreMemePeriode(POn2S,curv->Value(indicevertexonline+1),U1Period(),V1Period(),U2Period(),V2Period());
const IntSurf_PntOn2S aP2S1 = curv->Value(curv->NbPoints());
if(POn2S.Value().SquareDistance(aP2S1.Value()) > Precision::Confusion()*Precision::Confusion())
{
curv->InsertBefore(indicevertexonline+1,POn2S);
}
}
else
{
RecadreMemePeriode(POn2S,curv->Value(indicevertexonline+1),U1Period(),V1Period(),U2Period(),V2Period());
curv->InsertBefore(indicevertexonline+1,POn2S);
}

View File

@@ -97,3 +97,27 @@ inline const IntPatch_Point& IntPatch_WLine::Vertex (const Standard_Integer Inde
{
return svtx(Index);
}
inline void IntPatch_WLine::ClearVertexes()
{
svtx.Clear();
}
inline void IntPatch_WLine::RemoveVertex(const Standard_Integer theIndex)
{
if((theIndex < 1) || (theIndex > NbVertex()))
Standard_OutOfRange::Raise("Cannot delete not existing vertex");
svtx.Remove(theIndex);
}
inline void IntPatch_WLine::InsertVertexBefore( const Standard_Integer theIndex,
const IntPatch_Point& thePnt)
{
const Standard_Integer aNbVertexes = NbVertex();
Standard_Integer anIndex = Max(theIndex, 1);
if(anIndex > aNbVertexes)
svtx.Append(thePnt);
else
svtx.InsertBefore(theIndex, thePnt);
}

View File

@@ -77,7 +77,7 @@ void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
{
Standard_Integer i,nbvtx;
Standard_Real firstp,lastp;
const Standard_Real Tol = Precision::PConfusion() * 35.0;
const Standard_Real Tol = 1.001e-6;//Precision::PConfusion() * 35.0;
const IntPatch_IType typl = L->ArcType();
if(typl == IntPatch_Analytic) {

View File

@@ -29,7 +29,7 @@ package IntWalk
-- All the methods of the classes of this package are Internal.
--
uses
Standard, MMgt, TCollection, TColStd, gp, math, StdFail, IntSurf, IntImp
Standard, MMgt, TCollection, TColStd, gp, math, StdFail, IntSurf, IntImp, Adaptor3d, Bnd
is

View File

@@ -43,7 +43,9 @@ uses Vector from math,
VectorOfWalkingData from IntWalk,
Vec from gp,
Dir2d from gp,
PntOn2S from IntSurf
Pnt from gp,
PntOn2S from IntSurf,
Box2d from Bnd
raises NotDone from StdFail,
@@ -270,6 +272,59 @@ is
Clear (me: in out) is static protected;
---Purpose: Clears up internal containers
DistanceMinimizeByGradient (me: in out;
theASurf1 , theASurf2 : ThePSurface;
theU1, theV1, theU2, theV2: out Real from Standard;
theBox1, theBox2: Box2d from Bnd;
theStep0U1V1: Real from Standard = 1.0e-6;
theStep0U2V2: Real from Standard = 1.0e-6)
returns Boolean from Standard
is static protected;
---Purpose: Clears up internal containers
DistanceMinimizeByExtrema (me: in out;
theASurf : ThePSurface;
theP0 : Pnt from gp;
theU0, theV0: out Real from Standard;
theStep0U: Real from Standard = 1.0;
theStep0V: Real from Standard = 1.0)
returns Boolean from Standard
is static protected;
---Purpose: Clears up internal containers
SeekPointOnBoundary(me : in out;
theASurf1 , theASurf2 : ThePSurface ;
theU1, theV1, theU2, theV2: Real from Standard;
isTheFirst : Boolean from Standard;
theNCurve : Integer from Standard;
theExtendingType : Integer from Standard;
theParamTol : Real from Standard)
returns Boolean from Standard
is static protected;
-- Unites and correctly coordinates of work of
-- "DistanceMinimizeByGradient" and "DistanceMinimizeByExtrema" functions.
PutToBoundary(me : in out;
theASurf1 , theASurf2 : ThePSurface;
theNCurve : Integer from Standard)
-- Tries to extend existing intersection line
-- (as set of points) to surface's boundaries,
-- if it is possibly.
-- If line is scienter far from boundaries
-- or is (almost) parralel with some boundary,
-- extending is not required.
returns Boolean from Standard;
SeekAdditionalPoints( me : in out;
theASurf1 , theASurf2 : ThePSurface;
theMinNbPoints : Integer from Standard;
theNCurve : Integer from Standard)
returns Boolean from Standard;
-- Unites and correctly coordinates of work of
-- "DistanceMinimizeByGradient" and "DistanceMinimizeByExtrema" functions.
fields

File diff suppressed because it is too large Load Diff

View File

@@ -1,124 +0,0 @@
puts "================"
puts "OCC25416"
puts "================"
puts ""
#######################################################################
# Face/Face intersection algorithm gives different results for different order of the arguments
#######################################################################
# Check if list of xdistcs-command is valid
proc checkList {List Tolerance D_good Limit_Tol} {
set L1 [llength ${List}]
set L2 10
set L3 5
set N [expr (${L1} - ${L2})/${L3} + 1]
for {set i 1} {${i} <= ${N}} {incr i} {
set j1 [expr ${L2} + (${i}-1)*${L3}]
set j2 [expr ${j1} + 2]
set T [lindex ${List} ${j1}]
set D [lindex ${List} ${j2}]
#puts "i=${i} j1=${j1} j2=${j2} T=${T} D=${D}"
if { [expr abs(${D} - ${D_good})] > ${Tolerance} } {
puts "Error: T=${T} D=${D}"
}
if { ${Tolerance} > ${Limit_Tol} } {
if { [expr abs(${D} - ${D_good})] > ${Limit_Tol}
&& [expr abs(${D} - ${D_good})] <= ${Tolerance} } {
puts "Attention (critical value of tolerance) : T=${T} D=${D}"
}
}
}
}
puts "##############################"
puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
puts "##############################"
puts ""
puts ""
# bopcurves command
restore [locate_data_file bug25416_f1.brep] f1
restore [locate_data_file bug25416_f2.brep] f2
#############################
set log [bopcurves f1 f2 -2d]
#############################
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
#This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid.
set MaxTol 1.e-7
#This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid.
set GoodNbCurv 1
if {${Toler} > ${MaxTol}} {
puts "Error: Tolerance is too big!"
}
if {${NbCurv} != ${GoodNbCurv}} {
puts "Error: Curve Number is bad!"
}
#-------------
mksurface s1 f1
mksurface s2 f2
erase s1 s2
for {set i 1} {$i <= ${NbCurv}} {incr i} {
set log [dump c_$i]
set dumptrimres [regexp {Trimmed curve\nParameters : +([-0-9.+eE]+) +([-0-9.+eE]+)} ${log} full U1 U2]
if {${dumptrimres} == 0} {
regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
puts "Degree=${Degree}"
puts "Poles=${Poles}"
puts "KnotsPoles=${KnotsPoles}"
puts ""
set Knot 1
set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
regexp ${exp_string} ${log} full U1 Mult1
set Knot ${KnotsPoles}
set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
regexp ${exp_string} ${log} full U2 Mult2
}
puts "U1=${U1}"
puts "U2=${U2}"
if {[expr {$U2 - $U1}] < 1.0e-20} {
puts "Error: Wrong curve's range!"
}
dlog reset
dlog on
xdistcs c_$i s1 ${U1} ${U2} 10
set Log2 [dlog get]
set List2 [split ${Log2} {TD= \t\n}]
set Tolerance 1.0e-7
set Limit_Tol 1.0e-7
set D_good 0.
checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
dlog reset
dlog on
xdistcs c_$i s2 ${U1} ${U2} 10
set Log2 [dlog get]
set List2 [split ${Log2} {TD= \t\n}]
set Tolerance 1.0e-7
set Limit_Tol 1.0e-7
set D_good 0.
checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
}
smallview
fit
set only_screen_axo 1

View File

@@ -1,20 +0,0 @@
puts "==========="
puts "OCC25697"
puts "==========="
puts ""
##########################################################################################
# Regression : Section obtained after command "bsection" in Test Harness is incorrect.
##########################################################################################
restore [locate_data_file bug25697_shell_for_seam.brep] s1
restore [locate_data_file bug25697_prism.brep] p1
bsection result s1 p1 -n2d2
regexp {nb alone Vertices : +([-0-9.+eE]+)} [checksection result] full nb_alone_Vertices
if { ${nb_alone_Vertices} == 2 } {
puts "OK: Good result done by Boolean Operation algorithm"
} else {
puts "Error: Wrong result done by Boolean Operation algorithm"
}
set length 107.503

View File

@@ -1,63 +0,0 @@
puts "=========="
puts "OCC25697"
puts "=========="
puts ""
########################################################################################
# Regression : Section obtained after command "bsection" in Test Harness is incorrect.
########################################################################################
restore [locate_data_file bug25697_shell_for_seam.brep] b1
restore [locate_data_file bug25697_prism.brep] b2
explode b1 f
copy b1_1 b1
explode b2 f
copy b2_1 b2
#################################
set log [bopcurves b1 b2 -2d1]
#################################
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
set MaxTol 1.e-7
set GoodNbCurv 3
if { ${Toler} > ${MaxTol} } {
puts "Error: Tolerance is too big!"
}
if { ${NbCurv} != ${GoodNbCurv} } {
puts "Error: Curve Number is bad!"
}
#---------------
mksurface s1 b1
mksurface s2 b2
for {set i 1} {$i <= ${NbCurv}} {incr i} {
bounds c_$i u1 u2
dump u1 u2
dlog reset
dlog on
xdistcs c_$i s1 u1 u2 10
set Log2 [dlog get]
set List2 [split ${Log2} {TD= \t\n}]
set Tolerance 1.0e-7
set Limit_Tol 1.0e-7
set D_good 0.
checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
dlog reset
dlog on
xdistcs c_$i s2 u1 u2 10
set Log2 [dlog get]
set List2 [split ${Log2} {TD= \t\n}]
set Tolerance 1.0e-7
set Limit_Tol 1.0e-7
set D_good 0.
checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
}
smallview
fit
set only_screen_axo 1