1 // Created on: 2000-02-11
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <TopOpeBRepBuild_Tools.ixx>
19 #include <TopTools_IndexedMapOfShape.hxx>
21 #include <TopExp_Explorer.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Face.hxx>
28 #include <TopLoc_Location.hxx>
30 #include <BRep_TVertex.hxx>
31 #include <BRep_TEdge.hxx>
32 #include <BRep_TFace.hxx>
33 #include <BRep_Tool.hxx>
34 #include <BRep_GCurve.hxx>
35 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
36 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
37 #include <BRep_CurveRepresentation.hxx>
38 #include <BRep_PointRepresentation.hxx>
40 #include <Geom_Curve.hxx>
41 #include <Geom_Surface.hxx>
42 #include <Geom_Plane.hxx>
43 #include <Geom_TrimmedCurve.hxx>
45 #include <GeomAdaptor_Curve.hxx>
46 #include <GeomAdaptor_HCurve.hxx>
47 #include <GeomAdaptor_HSurface.hxx>
49 #include <Geom2d_Curve.hxx>
51 #include <Geom2dAdaptor_HCurve.hxx>
52 #include <Geom_RectangularTrimmedSurface.hxx>
53 #include <Geom2dAdaptor.hxx>
54 #include <GeomProjLib.hxx>
58 #include <Adaptor3d_HCurve.hxx>
59 #include <Adaptor3d_CurveOnSurface.hxx>
60 #include <Adaptor3d_HCurveOnSurface.hxx>
62 #include <ProjLib_ProjectedCurve.hxx>
63 #include <Extrema_LocateExtPC.hxx>
64 #include <BRepCheck_Wire.hxx>
67 void CheckEdge (const TopoDS_Edge& E,
68 const Standard_Real aMaxTol);
70 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
72 const Standard_Real aMaxTol);
74 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
75 const Adaptor3d_Curve& Other,
76 const Standard_Real Tol,
77 const Standard_Boolean SameParameter,
78 Standard_Real& aNewTolerance);
80 //=======================================================================
81 // Function : CorrectTolerances
83 //=======================================================================
84 void TopOpeBRepBuild_Tools::CorrectTolerances(const TopoDS_Shape& aShape,
85 const Standard_Real aMaxTol)
87 TopOpeBRepBuild_Tools::CorrectPointOnCurve(aShape, aMaxTol);
88 TopOpeBRepBuild_Tools::CorrectCurveOnSurface(aShape, aMaxTol);
91 //=======================================================================
92 // Function : CorrectPointOnCurve
94 //=======================================================================
95 void TopOpeBRepBuild_Tools::CorrectPointOnCurve(const TopoDS_Shape& S,
96 const Standard_Real aMaxTol)
98 Standard_Integer i, aNb;
99 TopTools_IndexedMapOfShape Edges;
100 TopExp::MapShapes (S, TopAbs_EDGE, Edges);
102 for (i=1; i<=aNb; i++) {
103 const TopoDS_Edge& E= TopoDS::Edge(Edges(i));
104 CheckEdge(E, aMaxTol);
108 //=======================================================================
109 // Function : CorrectCurveOnSurface
111 //=======================================================================
112 void TopOpeBRepBuild_Tools::CorrectCurveOnSurface(const TopoDS_Shape& S,
113 const Standard_Real aMaxTol)
115 Standard_Integer i, aNbFaces, j, aNbEdges;
116 TopTools_IndexedMapOfShape Faces;
117 TopExp::MapShapes (S, TopAbs_FACE, Faces);
119 aNbFaces=Faces.Extent();
120 for (i=1; i<=aNbFaces; i++) {
121 const TopoDS_Face& F= TopoDS::Face(Faces(i));
122 TopTools_IndexedMapOfShape Edges;
123 TopExp::MapShapes (F, TopAbs_EDGE, Edges);
124 aNbEdges=Edges.Extent();
125 for (j=1; j<=aNbEdges; j++) {
126 const TopoDS_Edge& E= TopoDS::Edge(Edges(j));
127 CorrectEdgeTolerance (E, F, aMaxTol);
132 //=======================================================================
133 // Function : CorrectEdgeTolerance
134 // purpose : Correct tolerances for Edge
135 //=======================================================================
136 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
137 const TopoDS_Face& S,
138 const Standard_Real aMaxTol)
141 // 1. Minimum of conditions to Perform
142 Handle (BRep_CurveRepresentation) myCref;
143 Handle (Adaptor3d_HCurve) myHCurve;
147 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
148 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
149 Standard_Boolean Degenerated, SameParameter, SameRange;
151 Standard_Integer unique = 0;
153 Degenerated = TE->Degenerated();
154 SameParameter = TE->SameParameter();
155 SameRange = TE->SameRange();
157 if (!SameRange && SameParameter) {
161 while (itcr.More()) {
162 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
163 if (cr->IsCurve3D()) {
165 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
173 return;//...No3DCurve
176 return;//...Multiple3DCurve;
179 if (myCref.IsNull() && !Degenerated) {
180 itcr.Initialize(TE->Curves());
181 while (itcr.More()) {
182 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
183 if (cr->IsCurveOnSurface()) {
191 else if (!myCref.IsNull() && Degenerated){
192 return ;//...InvalidDegeneratedFlag;
195 if (!myCref.IsNull()) {
196 Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref));
197 Standard_Real First,Last;
198 GCref->Range(First,Last);
201 return ;//InvalidRange;
205 if (myCref->IsCurve3D()) {
206 Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast
207 (myCref->Curve3D()->Transformed (myCref->Location().Transformation()));
208 GeomAdaptor_Curve GAC3d(C3d,First,Last);
209 myHCurve = new GeomAdaptor_HCurve(GAC3d);
211 else { // curve on surface
212 Handle(Geom_Surface) Sref = myCref->Surface();
213 Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation()));
214 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
215 Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref);
216 Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last);
217 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
218 myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
223 //===============================================
224 // 2. Tolerances in InContext
228 Standard_Boolean ok=Standard_True;
230 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
231 Standard_Real aNewTol=Tol;
233 Standard_Real First = myHCurve->FirstParameter();
234 Standard_Real Last = myHCurve->LastParameter();
236 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
237 const TopLoc_Location& Floc = S.Location();
238 const TopLoc_Location& TFloc = TF->Location();
239 const Handle(Geom_Surface)& Su = TF->Surface();
240 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
241 Standard_Boolean pcurvefound = Standard_False;
243 itcr.Initialize(TE->Curves());
244 while (itcr.More()) {
245 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
246 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
247 pcurvefound = Standard_True;
248 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
251 if (SameRange && (f != First || l != Last)) {
252 return ;//BRepCheck_InvalidSameRangeFlag;
255 Handle(Geom_Surface) Sb = cr->Surface();
256 Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation()));
257 Handle(Geom2d_Curve) PC = cr->PCurve();
258 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb);
259 Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
260 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
261 ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol);
263 // printf("(Edge,1) Tolerance=%15.10lg\n", aNewTol);
265 TE->UpdateTolerance(aNewTol);
267 if (cr->IsCurveOnClosedSurface()) {
268 // checkclosed = Standard_True;
269 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
270 ACS.Load(GHPC, GAHS); // sans doute inutile
271 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
274 TE->UpdateTolerance(aNewTol);
282 Handle(Geom_Plane) P;
283 Handle(Standard_Type) styp = Su->DynamicType();
284 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
285 P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface)::
286 DownCast(Su)->BasisSurface());
289 P = Handle(Geom_Plane)::DownCast(Su);
291 if (P.IsNull()) { // not a plane
292 return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface);
295 { // on fait la projection a la volee, comme BRep_Tool
296 P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation()));
297 //on projette Cref sur ce plan
298 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
300 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
301 GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
302 Handle(Geom_Curve) C3d = Gac.Curve();
303 Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane
304 (new Geom_TrimmedCurve(C3d,First,Last), P, P->Position().Direction(), Standard_True);
306 Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
308 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
309 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
310 Handle(Geom2dAdaptor_HCurve) GHPC =
311 new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter());
313 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
315 ok = Validate(myHCurve->Curve(),ACS,
316 Tol,Standard_True, aNewTol); // voir dub...
320 TE->UpdateTolerance(aNewTol);
323 }//end of if (!pcurvefound) {
324 } // end of 2. Tolerances in InContext
329 //=======================================================================
330 //function : Validate
332 //=======================================================================
333 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
334 const Adaptor3d_Curve& Other,
335 const Standard_Real Tol,
336 const Standard_Boolean SameParameter,
337 Standard_Real& aNewTolerance)
339 Standard_Real First, Last, MaxDistance, aD;
341 First = CRef.FirstParameter();
342 Last = CRef.LastParameter();
343 MaxDistance = Tol*Tol;
345 Standard_Integer i, aNC1=NCONTROL-1;
347 Standard_Boolean aFlag=Standard_False;
348 Standard_Boolean proj = (!SameParameter ||
349 First != Other.FirstParameter() ||
350 Last != Other.LastParameter());
354 for (i = 0; i < NCONTROL; i++) {
355 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
356 gp_Pnt pref = CRef.Value(prm);
357 gp_Pnt pother = Other.Value(prm);
359 aD=pref.SquareDistance(pother);
361 if (aD > MaxDistance) {
371 Extrema_LocateExtPC refd,otherd;
372 Standard_Real OFirst, OLast;
373 OFirst = Other.FirstParameter();
374 OLast = Other.LastParameter();
376 gp_Pnt pd = CRef.Value(First);
377 gp_Pnt pdo = Other.Value(OFirst);
379 aD = pd.SquareDistance(pdo);
380 if (aD > MaxDistance) {
385 pd = CRef.Value(Last);
386 pdo = Other.Value(OLast);
387 aD = pd.SquareDistance(pdo);
388 if (aD > MaxDistance) {
393 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
394 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
396 for (i = 2; i< aNC1; i++) {
397 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
398 gp_Pnt pref = CRef.Value(rprm);
400 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
401 gp_Pnt pother = Other.Value(oprm);
403 refd.Perform(pother,rprm);
404 if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) {
406 aD=refd.SquareDistance();
407 if (aD > MaxDistance) {
414 otherd.Perform(pref,oprm);
415 if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) {
417 if (otherd.IsDone()) {
418 aD=otherd.SquareDistance();
419 if (aD > MaxDistance) {
429 aD=sqrt (MaxDistance);
430 aNewTolerance=aD*1.05;
437 //=======================================================================
438 // Function : CheckEdge
439 // purpose : Correct tolerances for Vertices on Edge
440 //=======================================================================
441 void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol)
444 E.Orientation(TopAbs_FORWARD);
448 TopExp_Explorer aVExp;
449 aVExp.Init(E, TopAbs_VERTEX);
450 for (; aVExp.More(); aVExp.Next()) {
451 TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current());
453 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape());
454 const gp_Pnt& prep = TV->Pnt();
456 Standard_Real Tol, aD2, aNewTolerance, dd;
458 Tol =BRep_Tool::Tolerance(aVertex);
459 Tol = Max(Tol, BRep_Tool::Tolerance(E));
463 const TopLoc_Location& Eloc = E.Location();
464 BRep_ListIteratorOfListOfPointRepresentation itpr;
466 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
467 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
468 while (itcr.More()) {
469 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
470 const TopLoc_Location& loc = cr->Location();
471 TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location());
473 if (cr->IsCurve3D()) {
474 const Handle(Geom_Curve)& C = cr->Curve3D();
476 itpr.Initialize(TV->Points());
477 while (itpr.More()) {
478 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
479 if (pr->IsPointOnCurve(C,L)) {
480 Controlp = C->Value(pr->Parameter());
481 Controlp.Transform(L.Transformation());
482 aD2=prep.SquareDistance(Controlp);
484 aNewTolerance=sqrt(aD2)+dd;
485 if (aNewTolerance<aMaxTol)
486 TV->UpdateTolerance(aNewTolerance);
492 TopAbs_Orientation orv = aVertex.Orientation();
493 if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) {
494 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
496 if (orv==TopAbs_FORWARD)
497 Controlp = C->Value(GC->First());
499 Controlp = C->Value(GC->Last());
501 Controlp.Transform(L.Transformation());
502 aD2=prep.SquareDistance(Controlp);
505 aNewTolerance=sqrt(aD2)+dd;
506 if (aNewTolerance<aMaxTol)
507 TV->UpdateTolerance(aNewTolerance);
517 //=======================================================================
518 //function : CheckFaceClosed2d
520 //=======================================================================
522 Standard_Boolean TopOpeBRepBuild_Tools::CheckFaceClosed2d(const TopoDS_Face& theFace)
524 Standard_Boolean isClosed = Standard_True;
525 TopExp_Explorer ex(theFace,TopAbs_WIRE);
526 for (; ex.More() && isClosed; ex.Next()) {
527 const TopoDS_Wire& aW = TopoDS::Wire(ex.Current());
528 BRepCheck_Wire aWChk(aW);
529 BRepCheck_Status aStatus = aWChk.Orientation(theFace);
530 if (aStatus != BRepCheck_NoError)
531 isClosed = Standard_False;