#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.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:
aEps=RealEpsilon();
for (m=0; m<aNb; ++m) {
aV[m]=(!m)?
- *((TopoDS_Vertex*)(&aLV.First())):
- *((TopoDS_Vertex*)(&aLV.Last()));
+ *((TopoDS_Vertex*)(&aLV.First())):
+ *((TopoDS_Vertex*)(&aLV.Last()));
aP[m]=BRep_Tool::Pnt(aV[m]);
aR[m]=BRep_Tool::Tolerance(aV[m]);
}
return;
}// 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;
+ else { // if (aNb>2)
+ // 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 <Standard_Type.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepAlgo_AsDes,MMgt_TShared)
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;
+ TopTools_ListOfShape* pLSOld = aMap.ChangeSeek(OldS);
+ if (!pLSOld) {
+ 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));
+ //
+ Standard_Boolean InUp = !i ? Standard_False : Standard_True;
+ BackReplace(OldS, NewS, *pLSOld, InUp);
+ //
+ TopTools_ListOfShape* pLSNew = aMap.ChangeSeek(NewS);
+ if (!pLSNew) {
+ // filter the list
+ TopTools_MapOfOrientedShape aMS;
+ TopTools_ListIteratorOfListOfShape aIt(*pLSOld);
+ for (; aIt.More(); ) {
+ if (!aMS.Add(aIt.Value())) {
+ pLSOld->Remove(aIt);
+ }
+ else {
+ aIt.Next();
+ }
+ }
+ aMap.Bind(NewS, *pLSOld);
}
else {
- down.Bind(NewS,down(OldS));
+ // avoid duplicates
+ TopTools_MapOfOrientedShape aMS;
+ TopTools_ListIteratorOfListOfShape aIt(*pLSNew);
+ for (; aIt.More(); aIt.Next()) {
+ aMS.Add(aIt.Value());
+ }
+ //
+ aIt.Initialize(*pLSOld);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aS = aIt.Value();
+ if (aMS.Add(aS)) {
+ pLSNew->Append(aS);
+ }
+ }
}
- down.UnBind(OldS);
+ //
+ aMap.UnBind(OldS);
}
}
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPTools_AlgoTools.hxx>
#include <stdio.h>
#ifdef DRAW
TopoDS_Edge& E2)
{
TopoDS_Vertex V1[2],V2[2],V;
- // Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
-// TopExp::Vertices(E1,V1[0],V1[1]);
-// TopExp::Vertices(E2,V2[0],V2[1]);
-
+ //
TopExp::Vertices(E1,V1[0],V1[1], Standard_True);
TopExp::Vertices(E2,V2[0],V2[1], Standard_True);
// The first edge is the current one, the second edge is the next one.
// We check last vertex of the first edge first.
-// if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
-// if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
- // Modified by skv - Wed Dec 24 18:08:40 2003 OCC4455 End
+ //
return V;
}
//=======================================================================
//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();
+ TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aVC);
+ if (!pLV) {
+ aDMVV.Add(aVC, aLVN);
+ }
+ else {
+ pLV->Append(aV);
+ }
+ }
+ //
+ TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aV);
+ if (!pLV) {
+ aDMVV.Add(aV, aLVC);
+ }
+ else {
+ pLV->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);
}
-
//=======================================================================
//function : EdgeInter
//purpose :
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);
+ const TopTools_ListOfShape* pLV = theDMVV.Seek(theV);
+ if (pLV) {
+ TopTools_ListIteratorOfListOfShape aIt(*pLV);
+ 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);
+ }
+ }
+}
#include <TopTools_IndexedMapOfShape.hxx>
#include <Standard_Real.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
class BRepAlgo_AsDes;
class TopoDS_Face;
class BRepOffset_Offset;
//! 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
Standard_EXPORT static void 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);
+
+ //! 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.
Standard_EXPORT static void ConnexIntByInt (const TopoDS_Face& FI,
BRepOffset_Offset& OFI,
TopTools_DataMapOfShapeShape& MES,
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);
+ //! Fuses the chains of vertices in the theDMVV
+ //! and updates AsDes by replacing the old vertices
+ //! with the new ones.
+ Standard_EXPORT static void FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+ const Handle(BRepAlgo_AsDes)& theAsDes);
protected:
//---------------------------------------------------------------------------------
// 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.
{
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);
// -------------------------------------------------------------------
// 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 [V/E/F]",__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
+checkprops result1 -s 3.26459e+006
+checkprops result1 -v 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
+checkprops result2 -s 3.26459e+006
+checkprops result2 -v 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
+checkprops result1 -s 3.76166e+006
+checkprops result1 -v 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
+checkprops result2 -s 3.76166e+006
+checkprops result2 -v 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
+checkprops result1 -s 464088
+checkprops result1 -v 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
+checkprops result2 -s 464088
+checkprops result2 -v 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"
+ }
+}
puts "TODO ?OCC23068 ALL: ERROR. offsetperform operation not done."
-puts "TODO ?OCC23068 ALL: Error: The command cannot be built"
-puts "TODO ?OCC23068 ALL: result is not a topological shape!!!"
-puts "TODO ?OCC23068 ALL: TEST INCOMPLETE"
+puts "TODO ?OCC23068 ALL: Error : The volume of result shape "
## ======================================
## Grid : CCV002
puts "TODO OCC25406 ALL: Error : The volume of result shape is"
-puts "TODO OCC25406 ALL: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC25406 Windows: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
ellipse w1 0 0 0 15 10
mkedge w1 w1 0 pi/2
puts "TODO OCC23068 ALL: Error : The volume of result shape is"
-puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC23068 Windows: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC23068 ALL: Error: bsection of the result and s is not equal to zero"
ellipse w1 0 0 0 15 10
mkedge w1 w1 0 pi/2
-puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
-puts "TODO OCC26577 All: Error : is WRONG because number of SHELL entities in shape"
restore [locate_data_file bug26663_test_offset_K2.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}
checknbshapes result -ref [lrange [nbshapes s] 8 19]
-puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
puts "TODO OCC26577 All: Faulty shapes in variables faulty_1 to faulty"
restore [locate_data_file bug26663_test_offset_L3.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
-puts "TODO OCC26577 All: Error : is WRONG because number of SHELL entities in shape"
restore [locate_data_file bug26663_test_offset_L7.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}
checknbshapes result -ref [lrange [nbshapes s] 8 19]
-puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
puts "TODO OCC26577 All: Faulty shapes in variables faulty_1 to faulty"
restore [locate_data_file bug26663_test_offset_L9.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}