mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
Compare commits
1 Commits
CR670_FixS
...
CR670_FixS
Author | SHA1 | Date | |
---|---|---|---|
|
86b52ffdea |
@@ -74,7 +74,6 @@ is
|
||||
class CheckerSI;
|
||||
class ArgumentAnalyzer;
|
||||
class CheckResult;
|
||||
class ShellSplitter;
|
||||
--
|
||||
-- pointers
|
||||
--
|
||||
|
@@ -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()) {
|
||||
|
@@ -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,53 +221,153 @@ 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;
|
||||
BOPCol_MapOfOrientedShape aMP;
|
||||
// 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
|
||||
aIt.Initialize (myLoops);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
@@ -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,185 +447,131 @@ 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. 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;
|
||||
}
|
||||
// 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();
|
||||
//
|
||||
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();
|
||||
//
|
||||
if (aMSH.IsBound(aSolid)) {
|
||||
BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
|
||||
aLH.Append(aHole);
|
||||
// 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);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLH;
|
||||
aLH.Append(aHole);
|
||||
aMSH.Bind(aSolid, aLH);
|
||||
}
|
||||
//aBB.Add (aSolid, aHole);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLH;
|
||||
aLH.Append(aHole);
|
||||
aMSH.Bind(aSolid, aLH);
|
||||
}
|
||||
}
|
||||
}// 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());
|
||||
//
|
||||
if (aMFs.Add(aF)) {
|
||||
if (aNbA) {
|
||||
Bnd_Box aBox;
|
||||
BRepBndLib::Add(aF, aBox);
|
||||
aDMIS.Bind(k, aF);
|
||||
aTreeFiller.Add(k++, aBox);
|
||||
}
|
||||
}
|
||||
const TopoDS_Shape& aF=aIt.Value();
|
||||
aMF.Add(aF);
|
||||
}
|
||||
}
|
||||
aNbFI=aMF.Extent();
|
||||
//
|
||||
if (!aNbA) {
|
||||
// 7b. "Rest" faces treatment
|
||||
TopoDS_Solid aSolid;
|
||||
aBB.MakeSolid(aSolid);
|
||||
// 2 Process solids
|
||||
aSolidIt.Initialize(myAreas);
|
||||
for ( ; aSolidIt.More(); aSolidIt.Next()) {
|
||||
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
|
||||
//
|
||||
MakeInternalShells(aMFs, aLSI);
|
||||
//
|
||||
aItLS.Initialize(aLSI);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aSI=aItLS.Value();
|
||||
aBB.Add (aSolid, aSI);
|
||||
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);
|
||||
}
|
||||
myAreas.Append(aSolid);
|
||||
aMEF.Clear();
|
||||
BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
|
||||
//
|
||||
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);
|
||||
}
|
||||
//
|
||||
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;
|
||||
}
|
||||
//
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}// 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);
|
||||
}
|
||||
aMFx.Clear();
|
||||
//
|
||||
// 2.2 Make Internal Shells
|
||||
aLSI.Clear();
|
||||
MakeInternalShells(aMFs, aLSI);
|
||||
MakeInternalShells(aMFP, aLSI);
|
||||
//
|
||||
aItLS.Initialize(aLSI);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aSI=aItLS.Value();
|
||||
aBB.Add (*pSolid, aSI);
|
||||
// 2.3 Add them to aSolid
|
||||
aShellIt.Initialize(aLSI);
|
||||
for (; aShellIt.More(); aShellIt.Next()) {
|
||||
const TopoDS_Shape& aSI=aShellIt.Value();
|
||||
aBB.Add (aSolid, 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);
|
||||
//
|
||||
// 2.4 Remove faces aMFP from aMF
|
||||
aItMF.Initialize(aMFP);
|
||||
for (; aItMF.More(); aItMF.Next()) {
|
||||
const TopoDS_Shape& aF=aItMF.Key();
|
||||
aMF.Remove(aF);
|
||||
}
|
||||
}
|
||||
//
|
||||
aNbFI=aMFs.Extent();
|
||||
//
|
||||
aNbFI=aMF.Extent();
|
||||
if (!aNbFI) {
|
||||
break;
|
||||
}
|
||||
} //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;
|
||||
}
|
||||
|
@@ -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);
|
||||
@@ -287,7 +284,7 @@ void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts
|
||||
const BOPAlgo_ShapeBox& aSBk=aItDMISB.Value();
|
||||
const TopoDS_Shape& aFk=aSBk.Shape();
|
||||
if (aMF.Contains(aFk)) {
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const Bnd_Box& aBk=aSBk.Box();
|
||||
@@ -303,76 +300,67 @@ 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;
|
||||
//
|
||||
const BOPCol_ListOfInteger& aLIFP=aSelector.Indices();
|
||||
//
|
||||
// 2.7. Collect faces that are IN aSolid [ aLFIN ]
|
||||
BOPCol_ListOfShape aLFP(aAlr1);
|
||||
BOPCol_ListOfShape aLCBF(aAlr1);
|
||||
BOPCol_MapOfShape aMFDone(100, aAlr1);
|
||||
BOPCol_IndexedMapOfShape aME(100, aAlr1);
|
||||
//
|
||||
BOPTools::MapShapes(aSD, TopAbs_EDGE, aME);
|
||||
//
|
||||
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)) {
|
||||
continue;
|
||||
}
|
||||
TCollection_CompareOfInteger comp;
|
||||
SortTools_QuickSortOfInteger::Sort(anArray,comp);
|
||||
//
|
||||
// 2.7. Collect faces that are IN aSolid [ aLFIN ]
|
||||
BOPCol_ListOfShape aLFP(aAlr1);
|
||||
BOPCol_ListOfShape aLCBF(aAlr1);
|
||||
BOPCol_MapOfShape aMFDone(100, aAlr1);
|
||||
BOPCol_IndexedMapOfShape aME(100, aAlr1);
|
||||
aMFDone.Add(aFP);
|
||||
//
|
||||
BOPTools::MapShapes(aSD, TopAbs_EDGE, aME);
|
||||
iIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSD, aMEF, 1.e-14, myContext);
|
||||
//
|
||||
for (k = 1; k <= aNbFP; ++k) {
|
||||
nFP = anArray(k);
|
||||
const BOPAlgo_ShapeBox& aSBF=aDMISB.Find(nFP);
|
||||
const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
|
||||
if (aMFDone.Contains(aFP)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
aMFDone.Add(aFP);
|
||||
//
|
||||
iIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSD, aMEF, 1.e-14, myContext);
|
||||
//
|
||||
aLFP.Clear();
|
||||
aLFP.Append(aFP);
|
||||
//
|
||||
aItLI1.Initialize(aLIFP);
|
||||
for (; aItLI1.More(); aItLI1.Next()) {
|
||||
const TopoDS_Shape& aFx=aDMISB.Find(aItLI1.Value()).Shape();
|
||||
if (!aMFDone.Contains(aFx)) {
|
||||
aLFP.Append(aFx);
|
||||
}
|
||||
}
|
||||
//
|
||||
aLCBF.Clear();
|
||||
//----------------------------------------
|
||||
{
|
||||
Handle(NCollection_IncAllocator) aAlr2;
|
||||
aAlr2=new NCollection_IncAllocator();
|
||||
//
|
||||
BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aME, aLCBF, aAlr2);
|
||||
}
|
||||
//----------------------------------------
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFx=aItLS.Value();
|
||||
aMFDone.Add(aFx);
|
||||
if (iIsIN) {
|
||||
aLFIN.Append(aFx);
|
||||
}
|
||||
}
|
||||
}// for (; aItLI.More(); aItLI.Next()) {
|
||||
aLFP.Clear();
|
||||
aLFP.Append(aFP);
|
||||
//
|
||||
}
|
||||
aItLI1.Initialize(aLIFP);
|
||||
for (; aItLI1.More(); aItLI1.Next()) {
|
||||
const TopoDS_Shape& aFx=aDMISB.Find(aItLI1.Value()).Shape();
|
||||
if (!aMFDone.Contains(aFx)) {
|
||||
aLFP.Append(aFx);
|
||||
}
|
||||
}
|
||||
//
|
||||
aLCBF.Clear();
|
||||
//----------------------------------------
|
||||
{
|
||||
Handle(NCollection_IncAllocator) aAlr2;
|
||||
aAlr2=new NCollection_IncAllocator();
|
||||
//
|
||||
BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aME, aLCBF, aAlr2);
|
||||
}
|
||||
//----------------------------------------
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFx=aItLS.Value();
|
||||
aMFDone.Add(aFx);
|
||||
if (iIsIN) {
|
||||
aLFIN.Append(aFx);
|
||||
}
|
||||
}
|
||||
}// for (; aItLI.More(); aItLI.Next()) {
|
||||
//
|
||||
// 2.8. Store the results in theInParts, theDraftSolids
|
||||
aNbFIN=aLFIN.Extent();
|
||||
if (aNbFIN || aNbLIF) {
|
||||
aItLS.Initialize(aLIF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aLFIN.Append(aFI);
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aLFIN.Append(aFI);
|
||||
}
|
||||
theInParts.Bind(aSolid, aLFIN);
|
||||
}
|
||||
|
@@ -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;
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -1,2 +0,0 @@
|
||||
BRepCheck_SurfNormAnalyzer.hxx
|
||||
BRepCheck_SurfNormAnalyzer.cxx
|
@@ -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.
|
||||
@@ -58,7 +58,7 @@
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Real Controle(const TColgp_SequenceOfPnt& thePoints,
|
||||
const Handle(Geom_Plane)& thePlane)
|
||||
const Handle(Geom_Plane)& thePlane)
|
||||
{
|
||||
Standard_Real dfMaxDist=0.;
|
||||
Standard_Real a,b,c,d, dist;
|
||||
@@ -79,9 +79,9 @@ static Standard_Real Controle(const TColgp_SequenceOfPnt& thePoints,
|
||||
// the first vertex of theEdge2 in parametric space of theFace
|
||||
//=======================================================================
|
||||
inline static Standard_Boolean Is2DConnected(const TopoDS_Edge& theEdge1,
|
||||
const TopoDS_Edge& theEdge2,
|
||||
const Handle(Geom_Surface)& theSurface,
|
||||
const TopLoc_Location& theLocation)
|
||||
const TopoDS_Edge& theEdge2,
|
||||
const Handle(Geom_Surface)& theSurface,
|
||||
const TopLoc_Location& theLocation)
|
||||
{
|
||||
Standard_Real f,l;
|
||||
//TopLoc_Location aLoc;
|
||||
@@ -110,8 +110,8 @@ inline static Standard_Boolean Is2DConnected(const TopoDS_Edge& theEdge1,
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Boolean Is2DClosed(const TopoDS_Shape& theShape,
|
||||
const Handle(Geom_Surface)& theSurface,
|
||||
const TopLoc_Location& theLocation)
|
||||
const Handle(Geom_Surface)& theSurface,
|
||||
const TopLoc_Location& theLocation)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -164,9 +164,9 @@ BRepLib_FindSurface::BRepLib_FindSurface()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepLib_FindSurface::BRepLib_FindSurface(const TopoDS_Shape& S,
|
||||
const Standard_Real Tol,
|
||||
const Standard_Boolean OnlyPlane,
|
||||
const Standard_Boolean OnlyClosed)
|
||||
const Standard_Real Tol,
|
||||
const Standard_Boolean OnlyPlane,
|
||||
const Standard_Boolean OnlyClosed)
|
||||
{
|
||||
Init(S,Tol,OnlyPlane,OnlyClosed);
|
||||
}
|
||||
@@ -175,9 +175,9 @@ BRepLib_FindSurface::BRepLib_FindSurface(const TopoDS_Shape& S,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
const Standard_Real Tol,
|
||||
const Standard_Boolean OnlyPlane,
|
||||
const Standard_Boolean OnlyClosed)
|
||||
const Standard_Real Tol,
|
||||
const Standard_Boolean OnlyPlane,
|
||||
const Standard_Boolean OnlyClosed)
|
||||
{
|
||||
myTolerance = Tol;
|
||||
myTolReached = 0.;
|
||||
@@ -214,24 +214,24 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
// check the other edges
|
||||
for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
|
||||
if (!E.IsSame(ex.Current())) {
|
||||
j = 0;
|
||||
for(;;) {
|
||||
j++;
|
||||
BRep_Tool::CurveOnSurface(TopoDS::Edge(ex.Current()),
|
||||
PPC,SS,L,ff,ll,j);
|
||||
if (SS.IsNull()) {
|
||||
break;
|
||||
}
|
||||
if (SS == mySurface) {
|
||||
break;
|
||||
}
|
||||
SS.Nullify();
|
||||
}
|
||||
j = 0;
|
||||
for(;;) {
|
||||
j++;
|
||||
BRep_Tool::CurveOnSurface(TopoDS::Edge(ex.Current()),
|
||||
PPC,SS,L,ff,ll,j);
|
||||
if (SS.IsNull()) {
|
||||
break;
|
||||
}
|
||||
if (SS == mySurface) {
|
||||
break;
|
||||
}
|
||||
SS.Nullify();
|
||||
}
|
||||
|
||||
if (SS.IsNull()) {
|
||||
mySurface.Nullify();
|
||||
break;
|
||||
}
|
||||
if (SS.IsNull()) {
|
||||
mySurface.Nullify();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
// distances from neighboring points (_only_ same edge)
|
||||
// 2. Minimizing the weighed sum of squared deviations
|
||||
// compute coefficients of the sought plane.
|
||||
|
||||
|
||||
TColgp_SequenceOfPnt aPoints;
|
||||
TColStd_SequenceOfReal aWeight;
|
||||
|
||||
@@ -284,84 +284,64 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
{
|
||||
case GeomAbs_BezierCurve:
|
||||
{
|
||||
// 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.)
|
||||
// Degenerate
|
||||
continue;
|
||||
else
|
||||
{
|
||||
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;
|
||||
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
|
||||
{
|
||||
if (iPol<iNbPol)
|
||||
{
|
||||
aPoleNext = aPoles->Value(iPol+1);
|
||||
dfDistNext = aPolePrev.Distance(aPoleNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPolePrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPolePrev = aPoleNext;
|
||||
}
|
||||
}
|
||||
// Put all poles for bezier
|
||||
Handle(Geom_BezierCurve) GC = c.Bezier();
|
||||
Standard_Integer iNbPol = GC->NbPoles();
|
||||
if ( iNbPol < 2)
|
||||
// Degenerate
|
||||
continue;
|
||||
else
|
||||
{
|
||||
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;
|
||||
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
|
||||
{
|
||||
if (iPol<iNbPol)
|
||||
{
|
||||
aPoleNext = aPoles->Value(iPol+1);
|
||||
dfDistNext = aPolePrev.Distance(aPoleNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPolePrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPolePrev = aPoleNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GeomAbs_BSplineCurve:
|
||||
{
|
||||
// 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.)
|
||||
// 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)
|
||||
{
|
||||
if (iPol <= iNbPol - incr)
|
||||
{
|
||||
aPoleNext = aPoles->Value(iPol+incr);
|
||||
dfDistNext = aPolePrev.Distance(aPoleNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPolePrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPolePrev = aPoleNext;
|
||||
}
|
||||
}
|
||||
// Put all poles for bspline
|
||||
Handle(Geom_BSplineCurve) GC = c.BSpline();
|
||||
Standard_Integer iNbPol = GC->NbPoles();
|
||||
if ( iNbPol < 2)
|
||||
// Degenerate
|
||||
continue;
|
||||
else
|
||||
{
|
||||
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;
|
||||
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
|
||||
{
|
||||
if (iPol<iNbPol)
|
||||
{
|
||||
aPoleNext = aPoles->Value(iPol+1);
|
||||
dfDistNext = aPolePrev.Distance(aPoleNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPolePrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPolePrev = aPoleNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -371,41 +351,41 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
case GeomAbs_Hyperbola:
|
||||
case GeomAbs_Parabola:
|
||||
if (c.GetType() == GeomAbs_Line)
|
||||
// Two points on straight segment
|
||||
iNbPoints=2;
|
||||
// Two points on straight segment
|
||||
iNbPoints=2;
|
||||
else
|
||||
// Four points on otheranalitical curves
|
||||
iNbPoints=4;
|
||||
// Four points on otheranalitical curves
|
||||
iNbPoints=4;
|
||||
default:
|
||||
{
|
||||
// Put some points on other curves
|
||||
if (iNbPoints==0)
|
||||
iNbPoints = 15 + c.NbIntervals(GeomAbs_C3);
|
||||
Standard_Real dfDelta = (dfUl-dfUf)/(iNbPoints-1);
|
||||
Standard_Integer iPoint;
|
||||
Standard_Real dfU;
|
||||
gp_Pnt aPointPrev = c.Value(dfUf), aPointNext;
|
||||
Standard_Real dfDistPrev = 0., dfDistNext;
|
||||
for (iPoint=1, dfU=dfUf+dfDelta;
|
||||
iPoint<=iNbPoints;
|
||||
iPoint++, dfU+=dfDelta)
|
||||
{
|
||||
if (iPoint<iNbPoints)
|
||||
{
|
||||
aPointNext = c.Value(dfU);
|
||||
dfDistNext = aPointPrev.Distance(aPointNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPointPrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPointPrev = aPointNext;
|
||||
}
|
||||
// Put some points on other curves
|
||||
if (iNbPoints==0)
|
||||
iNbPoints = 15 + c.NbIntervals(GeomAbs_C3);
|
||||
Standard_Real dfDelta = (dfUl-dfUf)/(iNbPoints-1);
|
||||
Standard_Integer iPoint;
|
||||
Standard_Real dfU;
|
||||
gp_Pnt aPointPrev = c.Value(dfUf), aPointNext;
|
||||
Standard_Real dfDistPrev = 0., dfDistNext;
|
||||
for (iPoint=1, dfU=dfUf+dfDelta;
|
||||
iPoint<=iNbPoints;
|
||||
iPoint++, dfU+=dfDelta)
|
||||
{
|
||||
if (iPoint<iNbPoints)
|
||||
{
|
||||
aPointNext = c.Value(dfU);
|
||||
dfDistNext = aPointPrev.Distance(aPointNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPointPrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPointPrev = aPointNext;
|
||||
}
|
||||
} // default:
|
||||
} // switch (c.GetType()) ...
|
||||
} // for (ex.Init(S,TopAbs_EDGE); ex.More() && control; ex.Next()) ...
|
||||
|
||||
|
||||
if (aPoints.Length() < 3) {
|
||||
return;
|
||||
}
|
||||
@@ -434,14 +414,14 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
gp_XYZ p=aPoints(iPoint).XYZ()-aBaryCenter;
|
||||
Standard_Real w=aWeight(iPoint)/dfMaxWeight;
|
||||
aMat(1,1)+=w*p.X()*p.X();
|
||||
aMat(1,2)+=w*p.X()*p.Y();
|
||||
aMat(1,3)+=w*p.X()*p.Z();
|
||||
aMat(1,2)+=w*p.X()*p.Y();
|
||||
aMat(1,3)+=w*p.X()*p.Z();
|
||||
aMat(2,1)+=w*p.Y()*p.X();
|
||||
aMat(2,2)+=w*p.Y()*p.Y();
|
||||
aMat(2,3)+=w*p.Y()*p.Z();
|
||||
aMat(2,2)+=w*p.Y()*p.Y();
|
||||
aMat(2,3)+=w*p.Y()*p.Z();
|
||||
aMat(3,1)+=w*p.Z()*p.X();
|
||||
aMat(3,2)+=w*p.Z()*p.Y();
|
||||
aMat(3,3)+=w*p.Z()*p.Z();
|
||||
aMat(3,2)+=w*p.Z()*p.Y();
|
||||
aMat(3,3)+=w*p.Z()*p.Z();
|
||||
aVec(1) -= w*p.X();
|
||||
aVec(2) -= w*p.Y();
|
||||
aVec(3) -= w*p.Z();
|
||||
@@ -470,27 +450,26 @@ 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
|
||||
continue; // degeneration
|
||||
}
|
||||
for (Standard_Integer iP1=iPoint+1; iP1<=aPoints.Length(); iP1++) {
|
||||
gp_Vec aCross = gp_Vec(aFirstPnt,aPoints(iP1)) ^ aDir ;
|
||||
if (aCross.Magnitude() > dfSide*myTolerance) {
|
||||
Handle(Geom_Plane) aPlane2 = new Geom_Plane(aFirstPnt, aCross);
|
||||
Standard_Real dfDist2 = Controle (aPoints, aPlane2);
|
||||
if (dfDist2 < myTolerance) {
|
||||
myTolReached = dfDist2;
|
||||
mySurface = aPlane2;
|
||||
return;
|
||||
}
|
||||
if (dfDist2 < dfDist) {
|
||||
dfDist = dfDist2;
|
||||
aPlane = aPlane2;
|
||||
}
|
||||
}
|
||||
gp_Vec aCross = gp_Vec(aFirstPnt,aPoints(iP1)) ^ aDir ;
|
||||
if (aCross.Magnitude() > dfSide*myTolerance) {
|
||||
Handle(Geom_Plane) aPlane2 = new Geom_Plane(aFirstPnt, aCross);
|
||||
Standard_Real dfDist2 = Controle (aPoints, aPlane2);
|
||||
if (dfDist2 < myTolerance) {
|
||||
myTolReached = dfDist2;
|
||||
mySurface = aPlane2;
|
||||
return;
|
||||
}
|
||||
if (dfDist2 < dfDist) {
|
||||
dfDist = dfDist2;
|
||||
aPlane = aPlane2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -558,4 +537,3 @@ TopLoc_Location BRepLib_FindSurface::Location() const
|
||||
return myLocation;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -65,8 +65,8 @@ GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
|
||||
const Standard_Real aTol)
|
||||
:
|
||||
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.;
|
||||
@@ -104,12 +104,18 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
|
||||
dA=dU;
|
||||
dB=dV;
|
||||
if (dV>dU) {
|
||||
dA=dV;
|
||||
dB=dU;
|
||||
dA=dV;
|
||||
dB=dU;
|
||||
}
|
||||
//
|
||||
if (dB < Precision::PConfusion() || dA > dB * aTresh) {
|
||||
bFlag=!bFlag;
|
||||
aR=dA/dB;
|
||||
if (dB<Precision::PConfusion()) {
|
||||
bFlag=!bFlag;
|
||||
}
|
||||
else {
|
||||
if (aR>aTresh) {
|
||||
bFlag=!bFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -119,7 +125,7 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
|
||||
if(nbsu>40) nbsu = 40;
|
||||
if(nbsv>40) nbsv = 40;
|
||||
PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
|
||||
new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
|
||||
new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
|
||||
}
|
||||
//
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -309,9 +309,21 @@ is
|
||||
---C++: return const&
|
||||
returns HCurve2d from Adaptor2d;
|
||||
|
||||
Dump(me)
|
||||
ClearVertexes(me: mutable)
|
||||
is static;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
fields
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
|
||||
@@ -38,7 +38,7 @@ is
|
||||
ArretSurPoint, OK;
|
||||
|
||||
-- StepTooGreat, ConfusedPoint, StopOnPreviousPoint, StopOnPoint, OK
|
||||
|
||||
|
||||
-- class for definition of ressources on a biparametric surface
|
||||
|
||||
deferred generic class PSurfaceTool;
|
||||
@@ -67,7 +67,7 @@ is
|
||||
|
||||
imported VectorOfWalkingData;
|
||||
---Purpose: Defines a dynamic vector of work data.
|
||||
|
||||
|
||||
imported VectorOfInteger;
|
||||
---Purpose: Defines a dynamic vector of integer.
|
||||
|
||||
@@ -76,6 +76,6 @@ is
|
||||
-- 2 biparametric surfaces
|
||||
|
||||
generic class PWalking, TheInt2S;
|
||||
|
||||
|
||||
|
||||
end IntWalk;
|
||||
|
@@ -35,15 +35,17 @@ generic class IWalking from IntWalk (
|
||||
|
||||
|
||||
|
||||
uses Vector from math,
|
||||
SequenceOfInteger from TColStd,
|
||||
SequenceOfReal from TColStd,
|
||||
StatusDeflection from IntWalk,
|
||||
VectorOfInteger from IntWalk,
|
||||
VectorOfWalkingData from IntWalk,
|
||||
Vec from gp,
|
||||
Dir2d from gp,
|
||||
PntOn2S from IntSurf
|
||||
uses Vector from math,
|
||||
SequenceOfInteger from TColStd,
|
||||
SequenceOfReal from TColStd,
|
||||
StatusDeflection from IntWalk,
|
||||
VectorOfInteger from IntWalk,
|
||||
VectorOfWalkingData from IntWalk,
|
||||
Vec from gp,
|
||||
Dir2d from gp,
|
||||
Pnt from gp,
|
||||
PntOn2S from IntSurf,
|
||||
Box2d from Bnd
|
||||
|
||||
|
||||
raises NotDone from StdFail,
|
||||
@@ -270,7 +272,60 @@ 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
|
||||
|
||||
done : Boolean from Standard;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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
|
@@ -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
|
@@ -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
|
Reference in New Issue
Block a user