#include <IntTools_ShrunkRange.hxx>
#include <Precision.hxx>
//
+#include <NCollection_Array1.hxx>
+#include <algorithm>
+//
static
Standard_Real AngleWithRef(const gp_Dir& theD1,
const BOPTools_ListOfCoupleOfShape& theLCS,
const gp_Pnt& aP);
+//=======================================================================
+// function: BOPTools_AlgoTools_ComparePoints
+// purpose: implementation of IsLess() function for two points
+//=======================================================================
+struct BOPTools_AlgoTools_ComparePoints {
+ bool operator()(const gp_Pnt& theP1, const gp_Pnt& theP2)
+ {
+ for (Standard_Integer i = 1; i <= 3; ++i) {
+ if (theP1.Coord(i) < theP2.Coord(i)) {
+ return Standard_True;
+ }
+ else if (theP1.Coord(i) > theP2.Coord(i)) {
+ return Standard_False;
+ }
+ }
+ return Standard_False;
+ }
+};
+
//=======================================================================
// function: MakeConnexityBlocks
// purpose:
}// else if (aNb==2) {
//
else { // if (aNb>2)
- Standard_Real aTi, aDi, aDmax;
- gp_Pnt aPi, aP;
- gp_XYZ aXYZ(0.,0.,0.), aXYZi;
- BOPCol_ListIteratorOfListOfShape aIt;
+ // compute the point
//
- aIt.Initialize(aLV);
- for (; aIt.More(); aIt.Next()) {
- TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
- aPi=BRep_Tool::Pnt(aVi);
- aXYZi=aPi.XYZ();
- aXYZ=aXYZ+aXYZi;
+ // issue 0027540 - sum of doubles may depend on the order
+ // of addition, thus sort the coordinates for stable result
+ Standard_Integer i;
+ NCollection_Array1<gp_Pnt> aPoints(0, aNb-1);
+ BOPCol_ListIteratorOfListOfShape aIt(aLV);
+ for (i = 0; aIt.More(); aIt.Next(), ++i) {
+ const TopoDS_Vertex& aVi = *((TopoDS_Vertex*)(&aIt.Value()));
+ gp_Pnt aPi = BRep_Tool::Pnt(aVi);
+ aPoints(i) = aPi;
}
//
+ std::sort(aPoints.begin(), aPoints.end(), BOPTools_AlgoTools_ComparePoints());
+ //
+ gp_XYZ aXYZ(0., 0., 0.);
+ for (i = 0; i < aNb; ++i) {
+ aXYZ += aPoints(i).XYZ();
+ }
aXYZ.Divide((Standard_Real)aNb);
- aP.SetXYZ(aXYZ);
+ //
+ gp_Pnt aP(aXYZ);
+ //
+ // compute the tolerance for the new vertex
+ Standard_Real aTi, aDi, aDmax;
//
aDmax=-1.;
aIt.Initialize(aLV);
for (; aIt.More(); aIt.Next()) {
TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
- aPi=BRep_Tool::Pnt(aVi);
+ gp_Pnt aPi=BRep_Tool::Pnt(aVi);
aTi=BRep_Tool::Tolerance(aVi);
aDi=aP.SquareDistance(aPi);
aDi=sqrt(aDi);
#include <BRepAlgo_AsDes.ixx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
//=======================================================================
//function : BRepAlgo_AsDes
const TopoDS_Shape& NewS,
TopTools_ListOfShape& L)
{
+ TopTools_MapOfOrientedShape aMS;
TopTools_ListIteratorOfListOfShape it(L);
-
+ for (; it.More(); it.Next()) {
+ aMS.Add(it.Value());
+ }
+ it.Initialize(L);
while(it.More()) {
if (it.Value().IsSame(OldS)) {
TopAbs_Orientation O = it.Value().Orientation();
- L.InsertBefore(NewS.Oriented(O),it);
+ if (aMS.Add(NewS.Oriented(O))) {
+ L.InsertBefore(NewS.Oriented(O),it);
+ }
L.Remove(it);
}
else it.Next();
//function : Replace
//purpose :
//=======================================================================
-
void BRepAlgo_AsDes::Replace(const TopoDS_Shape& OldS,
- const TopoDS_Shape& NewS)
+ const TopoDS_Shape& NewS)
{
- Standard_Boolean InUp;
-
- if (up.IsBound(OldS)) {
- InUp = Standard_False;
- BackReplace (OldS,NewS,up(OldS),InUp);
- if (up.IsBound(NewS)) {
- up(NewS).Append(up(OldS));
+ for (Standard_Integer i = 0; i < 2; ++i) {
+ TopTools_DataMapOfShapeListOfShape& aMap = !i ? up : down;
+ if (!aMap.IsBound(OldS)) {
+ continue;
}
- else {
- up.Bind(NewS,up(OldS));
- }
- up.UnBind(OldS);
- }
-
- if (down.IsBound(OldS)) {
- InUp = Standard_True;
- BackReplace(OldS,NewS,down (OldS),InUp);
- if (down.IsBound(NewS)) {
- down(NewS).Append(down(OldS));
+ //
+ TopTools_ListOfShape& aLSOld = aMap.ChangeFind(OldS);
+ //
+ Standard_Boolean InUp = !i ? Standard_False : Standard_True;
+ BackReplace(OldS, NewS, aLSOld, InUp);
+ //
+ if (!aMap.IsBound(NewS)) {
+ // filter the list
+ TopTools_MapOfOrientedShape aMS;
+ TopTools_ListIteratorOfListOfShape aIt(aLSOld);
+ for (; aIt.More(); ) {
+ if (!aMS.Add(aIt.Value())) {
+ aLSOld.Remove(aIt);
+ }
+ else {
+ aIt.Next();
+ }
+ }
+ aMap.Bind(NewS, aLSOld);
}
else {
- down.Bind(NewS,down(OldS));
+ // avoid duplicates
+ TopTools_MapOfOrientedShape aMS;
+ TopTools_ListOfShape& aLSNew = aMap.ChangeFind(NewS);
+ TopTools_ListIteratorOfListOfShape aIt(aLSNew);
+ for (; aIt.More(); aIt.Next()) {
+ aMS.Add(aIt.Value());
+ }
+ //
+ aIt.Initialize(aLSOld);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aS = aIt.Value();
+ if (aMS.Add(aS)) {
+ aLSNew.Append(aS);
+ }
+ }
}
- down.UnBind(OldS);
+ //
+ aMap.UnBind(OldS);
}
}
Face from TopoDS,
Edge from TopoDS,
IndexedMapOfShape from TopTools,
+ IndexedDataMapOfShapeListOfShape from TopTools,
DataMapOfShapeShape from TopTools,
Real from Standard
Compute(myclass ; AsDes : AsDes from BRepAlgo;
F : Face from TopoDS;
NewEdges : IndexedMapOfShape from TopTools;
- Tol : Real from Standard);
+ Tol : Real from Standard;
+ theDMVV : out IndexedDataMapOfShapeListOfShape from TopTools);
---Purpose: Computes the intersections between the edges stored
-- is AsDes as descendants of <F> . Intersections is computed
-- between two edges if one of them is bound in NewEdges.
-
+ -- When all faces of the shape are treated the intersection
+ -- vertices have to be fused using the FuseVertices method.
+ -- theDMVV contains the vertices that should be fused
-- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin
-- Add another parameter: offset value.
AsDes : AsDes from BRepAlgo;
AsDes2d : AsDes from BRepAlgo;
Offset : Real from Standard;
- Tol : Real from Standard);
+ Tol : Real from Standard;
+ theDMVV : out IndexedDataMapOfShapeListOfShape from TopTools);
-- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 End
+ ---Purpose: Computes the intersection between the offset edges
+ -- stored in AsDes as descendatnds on <F>. All intersection
+ -- vertices will be stored in AsDes2d. When all faces of the
+ -- shape are treated the intersection vertices have to be fused
+ -- using the FuseVertices method.
+ -- theDMVV contains the vertices that should be fused.
+
+
+ FuseVertices(myclass;
+ theDMVV : IndexedDataMapOfShapeListOfShape from TopTools;
+ theAsDes : AsDes from BRepAlgo);
+ ---Purpose: Fuses the chains of vertices in the theDMVV
+ -- and updates AsDes by replacing the old vertices
+ -- with the new ones.
+
ExtentEdge(myclass ;
E : Edge from TopoDS;
#include <Bnd_Box.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <BRepTools.hxx>
+//
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPTools_AlgoTools.hxx>
+
#ifdef DRAW
#include <DBRep.hxx>
//=======================================================================
//function : Store
-//purpose :
+//purpose : The vertices are added despite of the coincidence with
+// already added vertices. When all vertices for all edges
+// are added the coinciding chains of vertices should be fused
+// using FuseVertices() method.
//=======================================================================
-
-static void Store (const TopoDS_Edge& E1,
- const TopoDS_Edge& E2,
- TopTools_ListOfShape& LV1,
- TopTools_ListOfShape& LV2,
- Handle(BRepAlgo_AsDes) AsDes,
- Standard_Real Tol)
+static void Store (const TopoDS_Edge& E1,
+ const TopoDS_Edge& E2,
+ const TopTools_ListOfShape& LV1,
+ const TopTools_ListOfShape& LV2,
+ Handle(BRepAlgo_AsDes) AsDes,
+ Standard_Real Tol,
+ TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
{
- //-------------------------------------------------------------
- // Test if the points of intersection correspond to existing
- // vertices. Otherwise add edges in the descendants.
- // Note: at this stage only vertices of intersection are in the descendants.
- //-------------------------------------------------------------
- const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
- const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
- TopTools_ListOfShape NewVOnE1;
- TopTools_ListOfShape NewVOnE2;
- gp_Pnt P,P1,P2;
- TopoDS_Vertex V1,V2;
- TopTools_ListIteratorOfListOfShape it, itLV1, itLV2;
- BRep_Builder B;
- TopAbs_Orientation O1,O2;
- Standard_Real U1,U2;
- Standard_Boolean OnE1,OnE2;
-
- for (itLV1.Initialize(LV1),itLV2.Initialize(LV2);
- itLV1.More();
- itLV1.Next() ,itLV2.Next()) {
-
- TopoDS_Vertex V = TopoDS::Vertex(itLV1.Value());
-
- U1 = (BRep_Tool::Degenerated(E1))?
- BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E1) :
- BRep_Tool::Parameter(V, E1);
- U2 = (BRep_Tool::Degenerated(E2))?
- BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E2) :
- BRep_Tool::Parameter(V, E2);
- O1 = V.Orientation();
- O2 = itLV2.Value().Orientation();
- P = BRep_Tool::Pnt(V);
- OnE1 = OnE2 = Standard_False;
-
- if (!VOnE1.IsEmpty()) {
- //-----------------------------------------------------------------
- // Find if the point of intersection corresponds to a vertex of E1.
- //-----------------------------------------------------------------
- for (it.Initialize(VOnE1); it.More(); it.Next()) {
- P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
- if (P.IsEqual(P1,Tol)) {
- V = TopoDS::Vertex(it.Value());
- V1 = V;
- OnE1 = Standard_True;
- break;
- }
- }
+ BRep_Builder aBB;
+ for (Standard_Integer i = 0; i < 2; ++i) {
+ const TopoDS_Edge& aE = !i ? E1 : E2;
+ const TopTools_ListOfShape& aLV = !i ? LV1 : LV2;
+ const TopTools_ListOfShape& aLVEx = AsDes->Descendant(aE);
+ if (aLVEx.IsEmpty()) {
+ if (aLV.Extent()) AsDes->Add(aE, aLV);
+ continue;
}
- if (!VOnE2.IsEmpty()) {
- if (OnE1) {
- //-----------------------------------------------------------------
- // Find if the vertex found on E1 is not already on E2.
- //-----------------------------------------------------------------
- for (it.Initialize(VOnE2); it.More(); it.Next()) {
- if (it.Value().IsSame(V)) {
- OnE2 = Standard_True;
- V2 = V;
- break;
- }
- }
+ //
+ TopTools_MapOfShape aMV;
+ TopTools_ListIteratorOfListOfShape aIt(aLV);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Vertex& aV = TopoDS::Vertex(aIt.Value());
+ if (!aMV.Add(aV)) {
+ continue;
}
- for (it.Initialize(VOnE2); it.More(); it.Next()) {
- //-----------------------------------------------------------------
- // Find if the point of intersection corresponds to a vertex of E2.
- //-----------------------------------------------------------------
- P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
- if (P.IsEqual(P2,Tol)) {
- V = TopoDS::Vertex(it.Value());
- V2 = V;
- OnE2 = Standard_True;
+ gp_Pnt aP = BRep_Tool::Pnt(aV);
+ //
+ TopTools_ListOfShape aLVC;
+ TopTools_ListIteratorOfListOfShape aItEx(aLVEx);
+ for (; aItEx.More(); aItEx.Next()) {
+ const TopoDS_Vertex& aVEx = TopoDS::Vertex(aItEx.Value());
+ if (aV.IsSame(aVEx)) {
break;
}
- }
- }
- if (OnE1 && OnE2) {
- if (!V1.IsSame(V2)) {
- //---------------------------------------------------------------
- // Two vertices are actually the same.
- // V2 will be replaced by V1.
- // update the parameters of vertex on edges.
- //---------------------------------------------------------------
- Standard_Real UV2;
- TopoDS_Edge EWE2;
- const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
-
- for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
- EWE2 = TopoDS::Edge(it.Value());
- TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
- UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
-// UV2 =
-// BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
- aLocalShape = V1.Oriented(TopAbs_INTERNAL);
- B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
-// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
-// UV2,EWE2,Tol);
+ gp_Pnt aPEx = BRep_Tool::Pnt(aVEx);
+ //
+ if (aP.IsEqual(aPEx, Tol)) {
+ aLVC.Append(aVEx);
}
- AsDes->Replace(V2,V1);
}
- }
- if (!OnE1) {
- if (OnE2) {
- TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
- B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-// U1,E1,Tol);
+ //
+ if (aItEx.More()) {
+ continue;
}
- NewVOnE1.Append(V.Oriented(O1));
- }
- if (!OnE2) {
- if (OnE1) {
- TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
- B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-// U2,E2,Tol);
+ //
+ if (aLVC.Extent()) {
+ TopTools_ListOfShape aLVN;
+ aLVN.Append(aV);
+ //
+ TopTools_ListIteratorOfListOfShape aItLV(aLVC);
+ for (; aItLV.More(); aItLV.Next()) {
+ const TopoDS_Shape& aVC = aItLV.Value();
+ if (!aDMVV.Contains(aVC)) {
+ aDMVV.Add(aVC, aLVN);
+ }
+ else {
+ aDMVV.ChangeFromKey(aVC).Append(aV);
+ }
+ }
+ //
+ if (!aDMVV.Contains(aV)) {
+ aDMVV.Add(aV, aLVC);
+ }
+ else {
+ aDMVV.ChangeFromKey(aV).Append(aLVC);
+ }
}
- NewVOnE2.Append(V.Oriented(O2));
+ //
+ aBB.UpdateVertex(aV, Tol);
+ AsDes->Add(aE, aV);
}
-
-#ifdef DRAW
- if (Inter2dAffichInt2d) {
- if (!OnE1 && !OnE2) {
- char name[256];
- sprintf(name,"VV_%d",NbNewVertices++);
- DBRep::Set(name,V);
- }
- }
-#endif
}
- if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1);
- if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2);
}
const TopoDS_Edge& E2,
const Handle(BRepAlgo_AsDes)& AsDes,
Standard_Real Tol,
- Standard_Boolean WithOri)
+ Standard_Boolean WithOri,
+ TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
{
#ifdef DRAW
if (Inter2dAffichInt2d) {
if (V1[j].IsNull()) continue;
for (Standard_Integer k = 0; k < 2; k++) {
if (V2[k].IsNull()) continue;
+ if (V1[j].IsSame(V2[k])) {
+ if (AsDes->HasAscendant(V1[j])) {
+ continue;
+ }
+ }
+ //
gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
Standard_Real Dist = P1.Distance(P2);
if (Dist < TolConf) {
+ Standard_Real aTol =
+ Max(BRep_Tool::Tolerance(V1[j]), BRep_Tool::Tolerance(V2[k]));
TopoDS_Vertex V = BRepLib_MakeVertex(P1);
U1 = (j == 0) ? f[1] : l[1];
U2 = (k == 0) ? f[2] : l[2];
+ //
TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-// Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
- Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
-
- if (!V1[j].IsSame(V2[k])) {
- Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
-
- aTol = Max(aTol, aTol2);
- }
-
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
-// B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-// B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-// U1,E1,Tol);
-// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-// U2,E2,Tol);
-// Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
+ //
LV1.Prepend(V.Oriented(V1[j].Orientation()));
LV2.Prepend(V.Oriented(V2[k].Orientation()));
}
//---------------------------------
// Vertex storage in DS.
//---------------------------------
-// Modified by skv - Tue Jan 13 15:14:30 2004 Begin
Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
-
TolStore = Max(TolStore, 10.*Tol);
-
- Store (E1,E2,LV1,LV2,AsDes,TolStore);
-// Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
-// Store (E1,E2,LV1,LV2,AsDes,Tol);
-// Modified by skv - Tue Jan 13 15:14:30 2004 End
+ Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
}
}
//=======================================================================
const Handle(BRepAlgo_AsDes)& AsDes,
Standard_Real Tol,
Standard_Boolean WithOri,
- gp_Pnt& Pref)
+ gp_Pnt& Pref,
+ TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
{
#ifdef DRAW
if (Inter2dAffichInt2d) {
if (V1[j].IsNull()) continue;
for (Standard_Integer k = 0; k < 2; k++) {
if (V2[k].IsNull()) continue;
+ if (V1[j].IsSame(V2[k])) {
+ if (AsDes->HasAscendant(V1[j])) {
+ continue;
+ }
+ }
+ //
gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
Standard_Real Dist = P1.Distance(P2);
TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-// U1,E1,Tol);
-// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-// U2,E2,Tol);
LV1.Prepend(V.Oriented(V1[j].Orientation()));
LV2.Prepend(V.Oriented(V2[k].Orientation()));
}
}
////-----------------------------------------------------
-
-// Modified by skv - Tue Jan 13 15:14:30 2004 Begin
Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
-
TolStore = Max(TolStore, 10.*Tol);
-
- Store (E1,E2,LV1,LV2,AsDes,TolStore);
-// Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
-// Store (E1,E2,LV1,LV2,AsDes,Tol);
-// Modified by skv - Tue Jan 13 15:14:30 2004 End
+ Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
}
}
void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes,
const TopoDS_Face& F,
const TopTools_IndexedMapOfShape& NewEdges,
- const Standard_Real Tol)
+ const Standard_Real Tol,
+ TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
{
#ifdef DRAW
NbF2d++;
if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
(NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
- EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True);
+ EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True, theDMVV);
// EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
}
it2LE.Next();
const Handle(BRepAlgo_AsDes)& AsDes,
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Offset,
- const Standard_Real Tol)
+ const Standard_Real Tol,
+ TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
// Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
{
for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
- AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+ AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
}
}
//
//
for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
- AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+ AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
}
//
for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
- AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+ AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
}
}
}
}
}
}
+
+
+//=======================================================================
+//function : MakeChain
+//purpose :
+//=======================================================================
+static void MakeChain(const TopoDS_Shape& theV,
+ const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+ TopTools_MapOfShape& theMDone,
+ BOPCol_ListOfShape& theChain)
+{
+ if (theMDone.Add(theV)) {
+ theChain.Append(theV);
+ if (theDMVV.Contains(theV)) {
+ const TopTools_ListOfShape& aLV = theDMVV.FindFromKey(theV);
+ TopTools_ListIteratorOfListOfShape aIt(aLV);
+ for (; aIt.More(); aIt.Next()) {
+ MakeChain(aIt.Value(), theDMVV, theMDone, theChain);
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : FuseVertices
+//purpose :
+//=======================================================================
+void BRepOffset_Inter2d::FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+ const Handle(BRepAlgo_AsDes)& theAsDes)
+{
+ BRep_Builder aBB;
+ TopTools_MapOfShape aMVDone;
+ Standard_Integer i, aNb = theDMVV.Extent();
+ for (i = 1; i <= aNb; ++i) {
+ const TopoDS_Vertex& aV = TopoDS::Vertex(theDMVV.FindKey(i));
+ //
+ // find chain of vertices
+ BOPCol_ListOfShape aLVChain;
+ MakeChain(aV, theDMVV, aMVDone, aLVChain);
+ //
+ if (aLVChain.Extent() < 2) {
+ continue;
+ }
+ //
+ // make new vertex
+ TopoDS_Vertex aVNew;
+ BOPTools_AlgoTools::MakeVertex(aLVChain, aVNew);
+ //
+ TopoDS_Vertex aVNewInt = TopoDS::Vertex(aVNew.Oriented(TopAbs_INTERNAL));
+ //
+ BOPCol_ListIteratorOfListOfShape aIt(aLVChain);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aVOld = aIt.Value();
+ // update the parameters on edges
+ TopoDS_Vertex aVOldInt = TopoDS::Vertex(aVOld.Oriented(TopAbs_INTERNAL));
+ const TopTools_ListOfShape& aLE = theAsDes->Ascendant(aVOld);
+ //
+ TopTools_ListIteratorOfListOfShape aItLE(aLE);
+ for (; aItLE.More(); aItLE.Next()) {
+ const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value());
+ Standard_Real aTolE = BRep_Tool::Tolerance(aE);
+ Standard_Real aT = BRep_Tool::Parameter(aVOldInt, aE);
+ aBB.UpdateVertex(aVNewInt, aT, aE, aTolE);
+ }
+ // and replace the vertex
+ theAsDes->Replace(aVOld, aVNew);
+ }
+ }
+}
//---------------------------------
// Intersection 2D on //
//---------------------------------
+ TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
TopTools_DataMapOfShapeShape aFacesOrigins; // offset face - initial face
TopTools_ListOfShape LFE;
BRepAlgo_Image IMOE;
{
const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
- BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol);
+ BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, aDMVV);
}
//----------------------------------------------
// Intersections 2d on caps.
{
const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
- BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol);
+ BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, aDMVV);
}
-
+ //
+ //
+ BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes);
//-------------------------------
// Unwinding of extended Faces.
//-------------------------------
//-----------------------------------------------
// Intersection of edges 2 by 2.
//-----------------------------------------------
+ TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
Standard_Integer i;
for (i = 1; i <= Modif.Extent(); i++) {
const TopoDS_Face& F = TopoDS::Face(Modif(i));
- BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol);
+ BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol, aDMVV);
}
-
+ //
+ BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
+ //
#ifdef OCCT_DEBUG
if (AffichInt2d) {
DEBVerticesControl (NewEdges,myAsDes);
Handle(BRepAlgo_AsDes)& theAsDes2d)
{
Standard_Real aTolF;
+ TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
TopExp_Explorer aExp(theShape, TopAbs_FACE);
//
for (; aExp.More(); aExp.Next()) {
aTolF = BRep_Tool::Tolerance(aF);
//
BRepOffset_Inter2d::ConnexIntByInt
- (aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, myOffset, aTolF);
+ (aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, myOffset, aTolF, aDMVV);
}
+ //
+ // fuse vertices on edges
+ BRepOffset_Inter2d::FuseVertices(aDMVV, theAsDes2d);
}
//=======================================================================
//---------------------------------------------------------------------------------
// Extension of neighbor edges of new edges and intersection between neighbors.
//--------------------------------------------------------------------------------
+ TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(FI);
BRepOffset_Inter2d::ConnexIntByInt (FI, MapSF(FI), MES, Build,
- AsDes, AsDes2d, myOffset, aCurrFaceTol);
+ AsDes, AsDes2d, myOffset, aCurrFaceTol, aDMVV);
}
+ //
+ // fuse vertices on edges
+ BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes2d);
//-----------------------------------------------------------
// Great restriction of new edges and update of AsDes.
//------------------------------------------ ----------------
}
}
+ aDMVV.Clear();
TopTools_ListIteratorOfListOfShape itLFE(LFE);
for (; itLFE.More(); itLFE.Next()) {
const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
- BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol);
+ BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, aDMVV);
}
//----------------------------------------------
// Intersections 2d on caps.
for (i = 1; i <= myFaces.Extent(); i++) {
const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
- BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol);
+ BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, aDMVV);
}
-
+ //
+ BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes);
//-------------------------------
// Unwinding of extended Faces.
//-------------------------------
//-----------------------------------------------
// Intersection of edges 2 by 2.
//-----------------------------------------------
+ TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
Standard_Integer i;
for (i = 1; i <= Modif.Extent(); i++) {
const TopoDS_Face& F = TopoDS::Face(Modif(i));
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(F);
- BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,aCurrFaceTol);
+ BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,aCurrFaceTol, aDMVV);
}
-
+ //
+ BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
+ //
#ifdef OCCT_DEBUG
if (AffichInt2dOld) {
DEBVerticesControlOld (NewEdges,myAsDes);
// -------------------------------------------------------------------
// Proceed with MakeLoops
-
+ TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
BRepOffset_Type OT = BRepOffset_Concave;
if (myRadius < 0.) OT = BRepOffset_Convex;
BRepOffset_Inter2d::Compute(myAsDes,
CurOF,
myEdges,
- myTol);
+ myTol,
+ aDMVV);
}
}
BRepOffset_Inter2d::Compute(myAsDes,
CurOF,
myEdges,
- myTol);
+ myTol,
+ aDMVV);
}
+ //
+ // fuse vertices on edges stored in AsDes
+ BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
// ------------
// unwinding
// ------------
typ = TopAbs_EDGE;
break;
+ case 'V' :
+ case 'v' :
+ typ = TopAbs_VERTEX;
+ break;
+
default :
return 1;
}
}
Exp.Next();
}
-
+ //
TColStd_Array1OfInteger OrderInd(1,MaxShapes);
-// gp_Pnt GPoint;
+ gp_Pnt GPoint;
GProp_GProps GPr;
-// Standard_Integer InOfminX = 1,aTemp;
Standard_Integer aTemp;
TColStd_Array1OfReal MidXYZ(1,MaxShapes); //X,Y,Z;
Standard_Boolean NoSort = Standard_True;
-
- // Computing of CentreOfMass
+ //
+ // Computing of CentreOfMass for edge and face
+ // and for vertex use its point
for (Index=1; Index <= MaxShapes; Index++) {
OrderInd.SetValue(Index,Index);
- BRepGProp::LinearProperties(aShapes(Index),GPr);
- gp_Pnt GPoint = GPr.CentreOfMass();
+ const TopoDS_Shape& aS = aShapes(Index);
+ if (aS.ShapeType() != TopAbs_VERTEX) {
+ BRepGProp::LinearProperties(aS, GPr);
+ GPoint = GPr.CentreOfMass();
+ }
+ else {
+ GPoint = BRep_Tool::Pnt(TopoDS::Vertex(aS));
+ }
MidXYZ.SetValue(Index, GPoint.X()*999 + GPoint.Y()*99 +
GPoint.Z()*0.9);
}
theCommands.Add("compound","compound [name1 name2 ..] compound",__FILE__,compound,g);
theCommands.Add("add","add name1 name2",__FILE__,add,g);
theCommands.Add("explode","explode name [Cd/C/So/Sh/F/W/E/V]",__FILE__,explode,g);
- theCommands.Add("nexplode","stable numbered explode for edge and face: nexplode name [F/E]",__FILE__,nexplode,g);
+ theCommands.Add("nexplode","stable numbered explode for vertex, edge and face: nexplode name [F/E/V]",__FILE__,nexplode,g);
theCommands.Add("exwire","exwire wirename",__FILE__,exwire,g);
theCommands.Add("emptycopy","emptycopy [copyshape] originalshape",__FILE__,emptycopy,g);
theCommands.Add("check","check shape1 shape2 ...",__FILE__,check,g);
--- /dev/null
+puts "=========================================================="
+puts "0027540: Run-to-run differences in the 3D Offset algorithm"
+puts "=========================================================="
+puts ""
+
+pload MODELING
+
+restore [locate_data_file bug27540_shapes1.brep] s
+explode s
+
+# make offset operations on two shapes
+# first shape
+offsetparameter 1e-7 c i
+# set offset 10 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_1 0
+set faces [explode s_1 f]
+foreach f $faces {
+ mksurface surf $f
+ set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+ if {$found && abs($z - 1) < 1.e-7} {
+ offsetonface $f 10
+ }
+}
+offsetperform result1
+set square 3.26459e+006
+set volume 1.067e+008
+checknbshapes result1 -vertex 28 -edge 44 -wire 20 -face 19 -shell 1 -solid 1
+
+
+# second shape
+offsetparameter 1e-7 c i
+# set offset 10 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_2 0
+set faces [explode s_2 f]
+foreach f $faces {
+ mksurface surf $f
+ set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+ if {$found && abs($z - 1) < 1.e-7} {
+ offsetonface $f 10
+ }
+}
+offsetperform result2
+set square 3.26459e+006
+set volume 1.067e+008
+checknbshapes result2 -vertex 28 -edge 44 -wire 20 -face 19 -shell 1 -solid 1
+
+
+# compare the results
+set vertices1 [nexplode result1 v]
+set vertices2 [nexplode result2 v]
+
+set nbv1 [llength $vertices1]
+
+for {set i 0} {$i < $nbv1} {incr i} {
+ set v1 [lindex $vertices1 $i]
+ set v2 [lindex $vertices2 $i]
+
+ mkpoint px $v1
+ set dump_v1 [dump px]
+
+ mkpoint px $v2
+ set dump_v2 [dump px]
+
+ if {$dump_v1 != $dump_v2} {
+ puts "Error: the results are not the same - $v1 and $v2"
+ }
+}
--- /dev/null
+puts "=========================================================="
+puts "0027540: Run-to-run differences in the 3D Offset algorithm"
+puts "=========================================================="
+puts ""
+
+pload MODELING
+
+restore [locate_data_file bug27540_shapes2.brep] s
+explode s
+
+# make offset operations on two shapes
+# first shape
+offsetparameter 1e-7 c i
+# set offset 30 for top faces (normal direction 0 0 1), 10 for all other faces
+offsetload s_1 10
+set faces [explode s_1 f]
+foreach f $faces {
+ mksurface surf $f
+ set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+ if {$found && abs($z - 1) < 1.e-7} {
+ offsetonface $f 30
+ }
+}
+offsetperform result1
+set square 3.76166e+006
+set volume 1.74521e+008
+checknbshapes result1 -vertex 36 -edge 56 -wire 24 -face 23 -shell 1 -solid 1
+
+
+# second shape
+offsetparameter 1e-7 c i
+# set offset 30 for top faces (normal direction 0 0 1), 10 for all other faces
+offsetload s_2 10
+set faces [explode s_2 f]
+foreach f $faces {
+ mksurface surf $f
+ set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+ if {$found && abs($z - 1) < 1.e-7} {
+ offsetonface $f 30
+ }
+}
+offsetperform result2
+set square 3.76166e+006
+set volume 1.74521e+008
+checknbshapes result2 -vertex 36 -edge 56 -wire 24 -face 23 -shell 1 -solid 1
+
+
+# compare the results
+set vertices1 [nexplode result1 v]
+set vertices2 [nexplode result2 v]
+
+set nbv1 [llength $vertices1]
+
+for {set i 0} {$i < $nbv1} {incr i} {
+ set v1 [lindex $vertices1 $i]
+ set v2 [lindex $vertices2 $i]
+
+ mkpoint px $v1
+ set dump_v1 [dump px]
+
+ mkpoint px $v2
+ set dump_v2 [dump px]
+
+ if {$dump_v1 != $dump_v2} {
+ puts "Error: the results are not the same - $v1 and $v2"
+ }
+}
--- /dev/null
+puts "=========================================================="
+puts "0027540: Run-to-run differences in the 3D Offset algorithm"
+puts "=========================================================="
+puts ""
+
+pload MODELING
+
+restore [locate_data_file bug27540_shapes3.brep] s
+explode s
+
+# make offset operations on two shapes
+# first shape
+offsetparameter 1e-7 c i
+# set offset 20 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_1 0
+set faces [explode s_1 f]
+foreach f $faces {
+ mksurface surf $f
+ set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+ if {$found && abs($z - 1) < 1.e-7} {
+ offsetonface $f 20
+ }
+}
+offsetperform result1
+set square 464088
+set volume 1.29909e+007
+checknbshapes result1 -vertex 48 -edge 74 -wire 32 -face 30 -shell 1 -solid 1
+
+
+# second shape
+offsetparameter 1e-7 c i
+# set offset 20 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_2 0
+set faces [explode s_2 f]
+foreach f $faces {
+ mksurface surf $f
+ set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+ if {$found && abs($z - 1) < 1.e-7} {
+ offsetonface $f 20
+ }
+}
+offsetperform result2
+set square 464088
+set volume 1.29909e+007
+checknbshapes result2 -vertex 48 -edge 74 -wire 32 -face 30 -shell 1 -solid 1
+
+
+# compare the results
+set vertices1 [nexplode result1 v]
+set vertices2 [nexplode result2 v]
+
+set nbv1 [llength $vertices1]
+
+for {set i 0} {$i < $nbv1} {incr i} {
+ set v1 [lindex $vertices1 $i]
+ set v2 [lindex $vertices2 $i]
+
+ mkpoint px $v1
+ set dump_v1 [dump px]
+
+ mkpoint px $v2
+ set dump_v2 [dump px]
+
+ if {$dump_v1 != $dump_v2} {
+ puts "Error: the results are not the same - $v1 and $v2"
+ }
+}