-// File: BRepBuilderAPI_Sewing.cxx
-// Created: Fri Mar 24 09:45:44 1995
-// Author: Jing Cheng MEI
-// <mei@junon>
+// Created on: 1995-03-24
+// Created by: Jing Cheng MEI
+// Copyright (c) 1995-1999 Matra Datavision
+// 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.
+
// dcl CCI60011 : Correction of degeneratedSection
// Improvement of SameParameter Edge to treat case of failure in BRepLib::SameParameter
// dcl Thu Aug 20 09:24:49 1998
#include <BRep_ListOfPointRepresentation.hxx>
#include <BRep_TVertex.hxx>
#include <Message_ProgressSentry.hxx>
-
-static void SortBox (const Handle(Bnd_HArray1OfBox) hSetBoxes,
- const Bnd_Box& aBox,
- TColStd_ListOfInteger& listIndex)
-{
- Standard_Integer i, nbBoxes = hSetBoxes->Length();
- for (i = 1; i <= nbBoxes; i++)
- if (!aBox.IsOut(hSetBoxes->Value(i)))
- listIndex.Append(i);
-}
+#include <BRepBuilderAPI_VertexInspector.hxx>
+#include <BRepBuilderAPI_CellFilter.hxx>
+#include <BRepBuilderAPI_BndBoxTreeSelector.hxx>
+#include <NCollection_UBTreeFiller.hxx>
//=======================================================================
//function : SameRange
if (TotLength > 0.0) {
gp_Pnt p1 = BRep_Tool::Pnt(TopoDS::Vertex(v1));
gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(v2));
- return (p1.Distance(p2) < TotLength/(1.2 * PI));
+ return (p1.Distance(p2) < TotLength/(1.2 * M_PI));
}
return Standard_False;
}
//check that edges merged valid way (for edges having length less than specified
//tolerance
- if(secForward)
- {
- if( V11.IsSame(V22) || V12.IsSame(V21) )
- return TopoDS_Edge();
- }
- else
+ // Check if edges are closed
+ Standard_Boolean isClosed1 = V11.IsSame(V12);
+ Standard_Boolean isClosed2 = V21.IsSame(V22);
+ if(!isClosed1 && !isClosed2)
{
- if( V11.IsSame(V21) || V12.IsSame(V22) )
- return TopoDS_Edge();
+ if(secForward )
+ {
+ if( V11.IsSame(V22) || V12.IsSame(V21) )
+ return TopoDS_Edge();
+ }
+ else
+ {
+ if( V11.IsSame(V21) || V12.IsSame(V22) )
+ return TopoDS_Edge();
+ }
}
//szv: do not reshape here!!!
gp_Pnt p21 = BRep_Tool::Pnt(V21);
gp_Pnt p22 = BRep_Tool::Pnt(V22);
- // Check if edges are closed
- Standard_Boolean isClosed1 = V11.IsSame(V12);
- Standard_Boolean isClosed2 = V21.IsSame(V22);
+
//Standard_Boolean isRev = Standard_False;
gp_Pnt pfirst;
// Retrieve second PCurves
TopLoc_Location loc2;
Handle(Geom_Surface) surf2;
+
//Handle(Geom2d_Curve) c2d2, c2d21;
// Standard_Real firstOld, lastOld;
if (whichSec == 1) itf2.Initialize(listFacesLast);
else itf2.Initialize(listFacesFirst);
Standard_Boolean isResEdge = Standard_False;
+ TopoDS_Face fac2;
for (; itf2.More(); itf2.Next()) {
Handle(Geom2d_Curve) c2d2, c2d21;
Standard_Real firstOld, lastOld;
- const TopoDS_Face& fac2 = TopoDS::Face(itf2.Value());
+ fac2 = TopoDS::Face(itf2.Value());
surf2 = BRep_Tool::Surface(fac2, loc2);
Standard_Boolean isSeam2 = ((IsUClosedSurface(surf2,edge2,loc2) || IsVClosedSurface(surf2,edge2,loc2)) &&
TopLoc_Location loc1;
Handle(Geom_Surface) surf1 = BRep_Tool::Surface(fac1, loc1);
+
Standard_Real first2d, last2d;
Standard_Boolean isSeam1 = ((IsUClosedSurface(surf1,edge1,loc1) || IsVClosedSurface(surf1,edge1,loc1)) &&
BRep_Tool::IsClosed(TopoDS::Edge(edge1),fac1));
}
}
- if(isResEdge)
- // Try to make the edge sameparameter
+ Standard_Real tolReached = Precision::Infinite();
+ Standard_Boolean isSamePar = Standard_False;
+ if( isResEdge)
+ {
SameParameter(edge);
-
- // Standard_Real tolReached = BRep_Tool::Tolerance(edge);
- //if (!BRep_Tool::SameParameter(edge)) return edge; //gka ????????
-
- if (firstCall && (!BRep_Tool::SameParameter(edge) || !isResEdge)) {
+ if( BRep_Tool::SameParameter(edge))
+ {
+ isSamePar = Standard_True;
+ tolReached = BRep_Tool::Tolerance(edge);
+ }
+ }
+
+
+ if (firstCall && ( !isResEdge || !isSamePar || tolReached > myTolerance)) {
Standard_Integer whichSecn = whichSec;
// Try to merge on the second section
- Standard_Boolean second_ok = Standard_True;
+ Standard_Boolean second_ok = Standard_False;
TopoDS_Edge s_edge = SameParameterEdge(edgeFirst,edgeLast,listFacesFirst,listFacesLast,
secForward,whichSecn,Standard_False);
- //if (s_edge.IsNull()) return s_edge; // gka version for free edges
- if (s_edge.IsNull()) second_ok = Standard_False;
- else if (!BRep_Tool::SameParameter(s_edge)) second_ok = Standard_False;
- else {
- edge = s_edge;
- whichSec = whichSecn;
+ if( !s_edge.IsNull())
+ {
+ Standard_Real tolReached_2 = BRep_Tool::Tolerance(s_edge);
+ second_ok = ( BRep_Tool::SameParameter(s_edge) && tolReached_2 < tolReached );
+ if( second_ok)
+ {
+ edge = s_edge;
+ whichSec = whichSecn;
+ tolReached = tolReached_2;
+ }
}
- if (!second_ok) {
+ if (!second_ok && !edge.IsNull()) {
GeomAdaptor_Curve c3dAdapt(c3d);
// Discretize edge curve
- Standard_Integer i, j, nbp = 15;
+ Standard_Integer i, j, nbp = 23;
Standard_Real deltaT = (last3d - first3d) / (nbp + 1);
TColgp_Array1OfPnt c3dpnt(1,nbp);
- for (i = 1; i <= nbp; i++) c3dpnt(i) = c3dAdapt.Value(first3d + i*deltaT);
+ for (i = 1; i <= nbp; i++)
+ c3dpnt(i) = c3dAdapt.Value(first3d + i*deltaT);
- Standard_Real u, v, dist, maxTol = -1.0;
+ Standard_Real dist = 0., maxTol = -1.0;
Standard_Boolean more = Standard_True;
for (j = 1; more; j++) {
Handle(Geom2d_Curve) c2d2;
BRep_Tool::CurveOnSurface(edge, c2d2, surf2, loc2, first, last, j);
+
more = !c2d2.IsNull();
if (more) {
+ Handle(Geom_Surface) aS = surf2;
+ if(!loc2.IsIdentity())
+ aS = Handle(Geom_Surface)::DownCast(surf2->Transformed ( loc2 ));
+ Standard_Real dist2 = 0.;
deltaT = (last - first) / (nbp + 1);
for (i = 1; i <= nbp; i++) {
- c2d2->Value(first + i*deltaT).Coord(u,v);
- dist = surf2->Value(u,v).Distance(c3dpnt(i));
- if (dist > maxTol) maxTol = dist;
+ gp_Pnt2d aP2d = c2d2->Value(first + i*deltaT);
+ gp_Pnt aP2(0.,0.,0.);
+ aS->D0(aP2d.X(),aP2d.Y(), aP2);
+ gp_Pnt aP1 = c3dpnt(i);
+ dist = aP2.SquareDistance(aP1);
+ if (dist > dist2)
+ dist2 = dist;
}
+ maxTol = Max(sqrt(dist2), Precision::Confusion());
}
}
-
- if (maxTol >= 0.) aBuilder.UpdateEdge(edge, maxTol);
+ if(maxTol >= 0. && maxTol < tolReached)
+ aBuilder.UpdateEdge(edge, maxTol);
aBuilder.SameParameter(edge,Standard_True);
}
}
else if ((n.Magnitude()>gp::Resolution()) && (normRef(j).Magnitude()>gp::Resolution())) {
nbComputedAngle++;
Standard_Real angular = n.Angle(normRef(j));
- if (angular > PI/2.) angular = PI - angular;
+ if (angular > M_PI/2.) angular = M_PI - angular;
cumulateAngular += angular;
}
}
ProjectPointsOnCurve(ptsRef,c3d,first,last,arrDist,arrPara,arrProj,Standard_False);
for( j = 1; j <= npt; j++ )
{
- if(arrDist(j) < 0. || arrDist(j) > myTolerance)
+ if(arrDist(j) < 0.)
continue;
if(dist < arrDist(j))
dist = arrDist(j);
}
else {
const TopoDS_Edge& Edge2 = TopoDS::Edge(seqSections(i));
- //gka
- seqSectionsNew.Append(Edge2);
- seqCandidatesNew.Append(i);
- /*TopoDS_Shape bnd = Edge2;
- if (mySectionBound.IsBound(bnd)) bnd = mySectionBound(bnd);
- //gka
- if (myBoundFaces.Contains(bnd)) {
- Standard_Boolean isOK = Standard_True;
- TopTools_ListIteratorOfListOfShape itf2(myBoundFaces.FindFromKey(bnd));
- for (; itf2.More() && isOK; itf2.Next()) {
- const TopoDS_Face& Face2 = TopoDS::Face(itf2.Value());
- // Check whether condition is satisfied
- isOK = !Faces1.Contains(Face2);
- if (!isOK) isOK = IsMergedClosed(Edge1,Edge2,Face2);
- }
- if (isOK) {
seqSectionsNew.Append(Edge2);
seqCandidatesNew.Append(i);
- }
- }*/
}
}
Standard_Integer nbSectionsNew = seqSectionsNew.Length();
if (nbSectionsNew > 1) {
-
+
// Evaluate distances between reference and other sections
TColStd_Array1OfBoolean arrForward(1,nbSectionsNew);
TColStd_Array1OfReal arrDistance(1,nbSectionsNew);
TColStd_Array1OfReal arrLen(1,nbSectionsNew);
TColStd_Array1OfReal arrMinDist(1,nbSectionsNew);
EvaluateDistances(seqSectionsNew,arrForward,arrDistance,arrLen,arrMinDist,1);
-
+
// Fill sequence of candidate indices sorted by distance
for (i = 2; i <= nbSectionsNew; i++) {
- if (arrDistance(i) >= 0.0 && arrLen(i) > myMinTolerance) {
+ Standard_Real aMaxDist = arrDistance(i);
+ if (aMaxDist >= 0.0 && aMaxDist <= myTolerance && arrLen(i) > myMinTolerance) {
+
// Reference section is connected to section #i
Standard_Boolean isInserted = Standard_False;
Standard_Integer j, ori = (arrForward(i)? 1 : 0);
for (j = 1; (j <= seqCandidates.Length()) && !isInserted; j++) {
- Standard_Integer aInd = seqCandidates.Value(j);//debug
Standard_Real aDelta = arrDistance(i) - arrDistance(seqCandidates.Value(j));
- //if (arrDistance(i) <= arrDistance(seqCandidates.Value(j))) {
+
if( aDelta < Precision::Confusion()) {
if(fabs(aDelta) > RealSmall() ||
}
}
}
-
- // Replace candidate indices
+
nbCandidates = seqCandidates.Length();
+ if (!nbCandidates)
+ return Standard_False; // Section has no candidates to merge
+
+ // Replace candidate indices
+
for (i = 1; i <= nbCandidates; i++)
seqCandidates(i) = seqCandidatesNew(seqCandidates(i));
+
}
- //}
-
+
if (!nbCandidates) return Standard_False; // Section has no candidates to merge
if (myNonmanifold && nbCandidates >1) {
const Standard_Boolean optionNonmanifold)
{
// Set tolerance and Perform options
- myTolerance = tolerance;
+ myTolerance = Max (tolerance, Precision::Confusion());
mySewing = optionSewing;
myAnalysis = optionAnalysis;
myCutting = optionCutting;
myNonmanifold = optionNonmanifold;
// Set min and max tolerances
- myMinTolerance = tolerance*1e-4; //szv: proposal
+ myMinTolerance = myTolerance * 1e-4; //szv: proposal
if (myMinTolerance < Precision::Confusion()) myMinTolerance = Precision::Confusion();
myMaxTolerance = Precision::Infinite();
// Set other modes
Standard_Integer i, nbVertices = aVertexNode.Extent();
// Create map of node -> vertices
TopTools_IndexedDataMapOfShapeListOfShape NodeVertices;
+ BRepBuilderAPI_CellFilter aFilter (Tolerance);
+ BRepBuilderAPI_VertexInspector anInspector (Tolerance);
for (i = 1; i <= nbVertices; i++) {
TopoDS_Shape vertex = aVertexNode.FindKey(i);
TopoDS_Vertex node = TopoDS::Vertex(aVertexNode(i));
TopTools_ListOfShape vlist;
vlist.Append(vertex);
NodeVertices.Add(node,vlist);
+ gp_Pnt aPnt = BRep_Tool::Pnt (TopoDS::Vertex (node));
+ aFilter.Add (NodeVertices.FindIndex (node), aPnt.XYZ());
+ anInspector.Add (aPnt.XYZ());
}
}
Standard_Integer nbNodes = NodeVertices.Extent();
#ifdef DEB
cout << "Glueing " << nbNodes << " nodes..." << endl;
#endif
- // Create array of boxes with nodes
- Handle(Bnd_HArray1OfBox) hSetBoxes = new Bnd_HArray1OfBox(1,nbNodes);
- Bnd_Box aBox;
- Standard_Real eps = Tolerance*0.5;
- for (i = 1; i <= nbNodes; i++) {
- gp_Pnt pt = BRep_Tool::Pnt(TopoDS::Vertex(NodeVertices.FindKey(i)));
- aBox.Set(pt);
- aBox.Enlarge(eps);
- hSetBoxes->SetValue(i,aBox);
- }
// Merge nearest nodes
TopTools_IndexedDataMapOfShapeShape NodeNearestNode;
Message_ProgressSentry aPS (theProgress, "Glueing nodes", 0, nbNodes, 1, Standard_True);
for (i = 1; i <= nbNodes && aPS.More(); i++, aPS.Next()) {
TopoDS_Vertex node1 = TopoDS::Vertex(NodeVertices.FindKey(i));
// Find near nodes
- TColStd_ListOfInteger listIndex;
- SortBox(hSetBoxes,hSetBoxes->Value(i),listIndex);
- if (listIndex.IsEmpty()) continue;
+ gp_Pnt pt1 = BRep_Tool::Pnt (node1);
+ anInspector.SetCurrent (pt1.XYZ());
+ gp_XYZ aPntMin = anInspector.Shift (pt1.XYZ(), -Tolerance);
+ gp_XYZ aPntMax = anInspector.Shift (pt1.XYZ(), Tolerance);
+ aFilter.Inspect (aPntMin, aPntMax, anInspector);
+ if (anInspector.ResInd().IsEmpty()) continue;
// Retrieve list of edges for the first node
const TopTools_ListOfShape& ledges1 = aNodeEdges(node1);
// Explore list of near nodes and fill the sequence of glued nodes
TopTools_SequenceOfShape SeqNodes;
TopTools_ListOfShape listNodesSameEdge;
- gp_Pnt pt1 = BRep_Tool::Pnt(node1);
- TColStd_ListIteratorOfListOfInteger iter1(listIndex);
+ //gp_Pnt pt1 = BRep_Tool::Pnt(node1);
+ TColStd_ListIteratorOfListOfInteger iter1(anInspector.ResInd());
for (; iter1.More(); iter1.Next()) {
TopoDS_Vertex node2 = TopoDS::Vertex(NodeVertices.FindKey(iter1.Value()));
if (node1 == node2) continue;
if (SeqNodes.Length())
NodeNearestNode.Add(node1,SeqNodes.First());
}
+ anInspector.ClearResList();
}
// Create new nodes for chained nearest nodes
if (NodeNearestNode.IsEmpty()) return Standard_False;
- hSetBoxes.Nullify();
return CreateNewNodes(NodeNearestNode,NodeVertices,aVertexNode,aNodeEdges);
}
{
Standard_Integer i, nbVertices = myVertexNode.Extent();
if (!nbVertices) return;
- // Create a sort box with vertices
+ // Create a box tree with vertices
Standard_Real eps = myTolerance*0.5;
- Handle(Bnd_HArray1OfBox) hSetBoxes = new Bnd_HArray1OfBox(1,nbVertices);
+ BRepBuilderAPI_BndBoxTree aTree;
+ NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller (aTree);
+ BRepBuilderAPI_BndBoxTreeSelector aSelector;
for (i = 1; i <= nbVertices; i++) {
gp_Pnt pt = BRep_Tool::Pnt(TopoDS::Vertex(myVertexNode.FindKey(i)));
Bnd_Box aBox;
aBox.Set(pt);
aBox.Enlarge(eps);
- hSetBoxes->ChangeValue(i) = aBox;
+ aTreeFiller.Add (i, aBox);
}
+ aTreeFiller.Fill();
+
Handle(Geom_Curve) c3d;
TopLoc_Location loc;
Standard_Real first, last;
GeomAdaptor_Curve adptC(c3d,first,last);
BndLib_Add3dCurve::Add(adptC,myTolerance,aGlobalBox);
// Sort vertices to find candidates
- TColStd_ListOfInteger listIndex;
- SortBox(hSetBoxes,aGlobalBox,listIndex);
+ aSelector.SetCurrent (aGlobalBox);
+ aTree.Select (aSelector);
// Skip bound if no node is in the boundind box
- if (!listIndex.Extent()) continue;
+ if (!aSelector.ResInd().Extent()) continue;
// Retrieve bound nodes
TopExp::Vertices(bound,V1,V2);
const TopoDS_Shape& Node1 = myVertexNode.FindFromKey(V1);
const TopoDS_Shape& Node2 = myVertexNode.FindFromKey(V2);
// Fill map of candidate vertices
- TColStd_ListIteratorOfListOfInteger itl(listIndex);
+ TColStd_ListIteratorOfListOfInteger itl(aSelector.ResInd());
for (; itl.More(); itl.Next()) {
const Standard_Integer index = itl.Value();
const TopoDS_Shape& Node = myVertexNode.FindFromIndex(index);
CandidateVertices.Add(vertex);
}
}
+ aSelector.ClearResList();
}
Standard_Integer nbCandidates = CandidateVertices.Extent();
if (!nbCandidates) continue;
Extrema_ExtPC locProj;
locProj.Initialize(GAC, first, last);
gp_Pnt pfirst = GAC.Value(first), plast = GAC.Value(last);
-
- for (Standard_Integer i1 = 1; i1 <= arrPnt.Length(); i1++) {
+ Standard_Integer find = 1;//(isConsiderEnds ? 1 : 2);
+ Standard_Integer lind = arrPnt.Length();//(isConsiderEnds ? arrPnt.Length() : arrPnt.Length() -1);
+
+ for (Standard_Integer i1 = find; i1 <= lind ; i1++) {
gp_Pnt pt = arrPnt(i1);
Standard_Real worktol = myTolerance;
Standard_Real distF2 = pfirst.SquareDistance(pt);
// Project current point on curve
locProj.Perform(pt);
if (locProj.IsDone() && locProj.NbExt() > 0) {
- Standard_Real dist2Min = Min(distF2,distL2);
+ Standard_Real dist2Min = (isConsiderEnds || i1 == find || i1 == lind ? Min(distF2,distL2) : Precision::Infinite());
Standard_Integer ind, indMin = 0;
for (ind = 1; ind <= locProj.NbExt(); ind++) {
Standard_Real dProj2 = locProj.SquareDistance(ind);
}
}
}
- if (distProj2 < worktol * worktol) {
+ if (distProj2 < worktol * worktol || !isConsiderEnds) {
arrDist(i1) = sqrt (distProj2);
arrPara(i1) = paramProj;
arrProj(i1) = ptProj;
}
}
}
+
+//=======================================================================
+//function : Inspect
+//purpose : Used for selection and storage of coinciding points
+//=======================================================================
+
+NCollection_CellFilter_Action BRepBuilderAPI_VertexInspector::Inspect (const Standard_Integer theTarget)
+{
+ /*gp_Pnt aPnt = gp_Pnt (myPoints.Value (theTarget - 1));
+ if (aPnt.SquareDistance (gp_Pnt (myCurrent)) <= myTol)
+ myResInd.Append (theTarget);*/
+
+ const gp_XYZ& aPnt = myPoints.Value (theTarget - 1);
+ Standard_Real aDx, aDy, aDz;
+ aDx = myCurrent.X() - aPnt.X();
+ aDy = myCurrent.Y() - aPnt.Y();
+ aDz = myCurrent.Z() - aPnt.Z();
+
+ if ((aDx*aDx <= myTol) && (aDy*aDy <= myTol) && (aDz*aDz <= myTol))
+ myResInd.Append (theTarget);
+ return CellFilter_Keep;
+}
+
+//=======================================================================
+//function : Context
+//purpose :
+//=======================================================================
+const Handle(BRepTools_ReShape)& BRepBuilderAPI_Sewing::GetContext() const
+{
+ return myReShape;
+}
+
+//=======================================================================
+//function : SetContext
+//purpose :
+//=======================================================================
+void BRepBuilderAPI_Sewing::SetContext(const Handle(BRepTools_ReShape)& theContext)
+{
+ myReShape = theContext;
+}
+