1 // Created on: 2000-02-11
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
22 #include <TopOpeBRepBuild_Tools.ixx>
25 #include <TopTools_IndexedMapOfShape.hxx>
27 #include <TopExp_Explorer.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <TopoDS_Face.hxx>
34 #include <TopLoc_Location.hxx>
36 #include <BRep_TVertex.hxx>
37 #include <BRep_TEdge.hxx>
38 #include <BRep_TFace.hxx>
39 #include <BRep_Tool.hxx>
40 #include <BRep_GCurve.hxx>
41 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
42 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
43 #include <BRep_CurveRepresentation.hxx>
44 #include <BRep_PointRepresentation.hxx>
46 #include <Geom_Curve.hxx>
47 #include <Geom_Surface.hxx>
48 #include <Geom_Plane.hxx>
49 #include <Geom_TrimmedCurve.hxx>
51 #include <GeomAdaptor_Curve.hxx>
52 #include <GeomAdaptor_HCurve.hxx>
53 #include <GeomAdaptor_HSurface.hxx>
55 #include <Geom2d_Curve.hxx>
57 #include <Geom2dAdaptor_HCurve.hxx>
58 #include <Geom_RectangularTrimmedSurface.hxx>
59 #include <Geom2dAdaptor.hxx>
60 #include <GeomProjLib.hxx>
64 #include <Adaptor3d_HCurve.hxx>
65 #include <Adaptor3d_CurveOnSurface.hxx>
66 #include <Adaptor3d_HCurveOnSurface.hxx>
68 #include <ProjLib_ProjectedCurve.hxx>
69 #include <Extrema_LocateExtPC.hxx>
70 #include <BRepCheck_Wire.hxx>
73 void CheckEdge (const TopoDS_Edge& E,
74 const Standard_Real aMaxTol);
76 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
78 const Standard_Real aMaxTol);
80 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
81 const Adaptor3d_Curve& Other,
82 const Standard_Real Tol,
83 const Standard_Boolean SameParameter,
84 Standard_Real& aNewTolerance);
86 //=======================================================================
87 // Function : CorrectTolerances
89 //=======================================================================
90 void TopOpeBRepBuild_Tools::CorrectTolerances(const TopoDS_Shape& aShape,
91 const Standard_Real aMaxTol)
93 TopOpeBRepBuild_Tools::CorrectPointOnCurve(aShape, aMaxTol);
94 TopOpeBRepBuild_Tools::CorrectCurveOnSurface(aShape, aMaxTol);
97 //=======================================================================
98 // Function : CorrectPointOnCurve
100 //=======================================================================
101 void TopOpeBRepBuild_Tools::CorrectPointOnCurve(const TopoDS_Shape& S,
102 const Standard_Real aMaxTol)
104 Standard_Integer i, aNb;
105 TopTools_IndexedMapOfShape Edges;
106 TopExp::MapShapes (S, TopAbs_EDGE, Edges);
108 for (i=1; i<=aNb; i++) {
109 const TopoDS_Edge& E= TopoDS::Edge(Edges(i));
110 CheckEdge(E, aMaxTol);
114 //=======================================================================
115 // Function : CorrectCurveOnSurface
117 //=======================================================================
118 void TopOpeBRepBuild_Tools::CorrectCurveOnSurface(const TopoDS_Shape& S,
119 const Standard_Real aMaxTol)
121 Standard_Integer i, aNbFaces, j, aNbEdges;
122 TopTools_IndexedMapOfShape Faces;
123 TopExp::MapShapes (S, TopAbs_FACE, Faces);
125 aNbFaces=Faces.Extent();
126 for (i=1; i<=aNbFaces; i++) {
127 const TopoDS_Face& F= TopoDS::Face(Faces(i));
128 TopTools_IndexedMapOfShape Edges;
129 TopExp::MapShapes (F, TopAbs_EDGE, Edges);
130 aNbEdges=Edges.Extent();
131 for (j=1; j<=aNbEdges; j++) {
132 const TopoDS_Edge& E= TopoDS::Edge(Edges(j));
133 CorrectEdgeTolerance (E, F, aMaxTol);
138 //=======================================================================
139 // Function : CorrectEdgeTolerance
140 // purpose : Correct tolerances for Edge
141 //=======================================================================
142 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
143 const TopoDS_Face& S,
144 const Standard_Real aMaxTol)
147 // 1. Minimum of conditions to Perform
148 Handle (BRep_CurveRepresentation) myCref;
149 Handle (Adaptor3d_HCurve) myHCurve;
153 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
154 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
155 Standard_Boolean Degenerated, SameParameter, SameRange;
157 Standard_Integer unique = 0;
159 Degenerated = TE->Degenerated();
160 SameParameter = TE->SameParameter();
161 SameRange = TE->SameRange();
163 if (!SameRange && SameParameter) {
167 while (itcr.More()) {
168 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
169 if (cr->IsCurve3D()) {
171 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
179 return;//...No3DCurve
182 return;//...Multiple3DCurve;
185 if (myCref.IsNull() && !Degenerated) {
186 itcr.Initialize(TE->Curves());
187 while (itcr.More()) {
188 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
189 if (cr->IsCurveOnSurface()) {
197 else if (!myCref.IsNull() && Degenerated){
198 return ;//...InvalidDegeneratedFlag;
201 if (!myCref.IsNull()) {
202 const Handle(BRep_GCurve)& GCref = *((Handle(BRep_GCurve)*)&myCref);
203 Standard_Real First,Last;
204 GCref->Range(First,Last);
207 return ;//InvalidRange;
211 if (myCref->IsCurve3D()) {
212 Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast
213 (myCref->Curve3D()->Transformed (myCref->Location().Transformation()));
214 GeomAdaptor_Curve GAC3d(C3d,First,Last);
215 myHCurve = new GeomAdaptor_HCurve(GAC3d);
217 else { // curve on surface
218 Handle(Geom_Surface) Sref = myCref->Surface();
219 Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation()));
220 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
221 Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref);
222 Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last);
223 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
224 myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
229 //===============================================
230 // 2. Tolerances in InContext
234 Standard_Boolean ok=Standard_True;
236 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
237 Standard_Real aNewTol=Tol;
239 Standard_Real First = myHCurve->FirstParameter();
240 Standard_Real Last = myHCurve->LastParameter();
242 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
243 const TopLoc_Location& Floc = S.Location();
244 const TopLoc_Location& TFloc = TF->Location();
245 const Handle(Geom_Surface)& Su = TF->Surface();
246 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
247 // Standard_Boolean checkclosed = Standard_False;
248 Standard_Boolean pcurvefound = Standard_False;
250 itcr.Initialize(TE->Curves());
251 while (itcr.More()) {
252 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
253 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
254 pcurvefound = Standard_True;
255 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
258 if (SameRange && (f != First || l != Last)) {
259 return ;//BRepCheck_InvalidSameRangeFlag);
261 return; //BRepCheck_InvalidSameParameterFlag);
265 Handle(Geom_Surface) Sb = cr->Surface();
266 Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation()));
267 Handle(Geom2d_Curve) PC = cr->PCurve();
268 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb);
269 Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
270 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
271 ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol);
273 if (cr->IsCurveOnClosedSurface()) {
274 //return ;// BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
277 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
280 //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
282 // printf("(Edge,1) Tolerance=%15.10lg\n", aNewTol);
284 TE->UpdateTolerance(aNewTol);
287 if (cr->IsCurveOnClosedSurface()) {
288 // checkclosed = Standard_True;
289 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
290 ACS.Load(GAHS); // sans doute inutile
291 ACS.Load(GHPC); // meme remarque...
292 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
294 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
296 //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
298 // printf("(Edge,2) Tolerance=%15.10lg\n", aNewTol);
300 TE->UpdateTolerance(aNewTol);
308 Handle(Geom_Plane) P;
309 Handle(Standard_Type) styp = Su->DynamicType();
310 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
311 P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface)::
312 DownCast(Su)->BasisSurface());
315 P = Handle(Geom_Plane)::DownCast(Su);
317 if (P.IsNull()) { // not a plane
318 return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface);
321 else {// on fait la projection a la volee, comme BRep_Tool
322 P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation()));
323 //on projette Cref sur ce plan
324 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
326 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
327 GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
328 Handle(Geom_Curve) C3d = Gac.Curve();
329 Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane
330 (new Geom_TrimmedCurve(C3d,First,Last), P, P->Position().Direction(), Standard_True);
332 Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
334 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
335 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
336 Handle(Geom2dAdaptor_HCurve) GHPC =
337 new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter());
339 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
341 ok = Validate(myHCurve->Curve(),ACS,
342 Tol,Standard_True, aNewTol); // voir dub...
344 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
345 // printf("(Edge,3) Tolerance=%15.10lg\n", aNewTol);
347 TE->UpdateTolerance(aNewTol);
351 }//end of if (!pcurvefound) {
352 } // end of 2. Tolerances in InContext
357 //=======================================================================
358 //function : Validate
360 //=======================================================================
361 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
362 const Adaptor3d_Curve& Other,
363 const Standard_Real Tol,
364 const Standard_Boolean SameParameter,
365 Standard_Real& aNewTolerance)
367 Standard_Real First, Last, MaxDistance, aD;
369 First = CRef.FirstParameter();
370 Last = CRef.LastParameter();
371 MaxDistance = Tol*Tol;
373 Standard_Integer i, aNC1=NCONTROL-1;
375 Standard_Boolean aFlag=Standard_False;
376 Standard_Boolean proj = (!SameParameter ||
377 First != Other.FirstParameter() ||
378 Last != Other.LastParameter());
382 for (i = 0; i < NCONTROL; i++) {
383 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
384 gp_Pnt pref = CRef.Value(prm);
385 gp_Pnt pother = Other.Value(prm);
387 aD=pref.SquareDistance(pother);
389 if (aD > MaxDistance) {
399 Extrema_LocateExtPC refd,otherd;
400 Standard_Real OFirst, OLast;
401 OFirst = Other.FirstParameter();
402 OLast = Other.LastParameter();
404 gp_Pnt pd = CRef.Value(First);
405 gp_Pnt pdo = Other.Value(OFirst);
407 aD = pd.SquareDistance(pdo);
408 if (aD > MaxDistance) {
413 pd = CRef.Value(Last);
414 pdo = Other.Value(OLast);
415 aD = pd.SquareDistance(pdo);
416 if (aD > MaxDistance) {
421 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
422 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
424 for (i = 2; i< aNC1; i++) {
425 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
426 gp_Pnt pref = CRef.Value(rprm);
428 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
429 gp_Pnt pother = Other.Value(oprm);
431 refd.Perform(pother,rprm);
432 if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) {
434 aD=refd.SquareDistance();
435 if (aD > MaxDistance) {
442 otherd.Perform(pref,oprm);
443 if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) {
445 if (otherd.IsDone()) {
446 aD=otherd.SquareDistance();
447 if (aD > MaxDistance) {
457 aD=sqrt (MaxDistance);
458 aNewTolerance=aD*1.05;
465 //=======================================================================
466 // Function : CheckEdge
467 // purpose : Correct tolerances for Vertices on Edge
468 //=======================================================================
469 void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol)
472 E.Orientation(TopAbs_FORWARD);
476 TopExp_Explorer aVExp;
477 aVExp.Init(E, TopAbs_VERTEX);
478 for (; aVExp.More(); aVExp.Next()) {
479 TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current());
481 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape());
482 const gp_Pnt& prep = TV->Pnt();
484 Standard_Real Tol, aD2, aNewTolerance, dd;
486 Tol =BRep_Tool::Tolerance(aVertex);
487 Tol = Max(Tol, BRep_Tool::Tolerance(E));
491 const TopLoc_Location& Eloc = E.Location();
492 BRep_ListIteratorOfListOfPointRepresentation itpr;
494 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
495 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
496 while (itcr.More()) {
497 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
498 const TopLoc_Location& loc = cr->Location();
499 TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location());
501 if (cr->IsCurve3D()) {
502 const Handle(Geom_Curve)& C = cr->Curve3D();
504 itpr.Initialize(TV->Points());
505 while (itpr.More()) {
506 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
507 if (pr->IsPointOnCurve(C,L)) {
508 Controlp = C->Value(pr->Parameter());
509 Controlp.Transform(L.Transformation());
510 aD2=prep.SquareDistance(Controlp);
512 aNewTolerance=sqrt(aD2)+dd;
513 // printf("(Vert,1) Tolerance=%15.10lg\n", aNewTolerance);
514 if (aNewTolerance<aMaxTol)
515 TV->UpdateTolerance(aNewTolerance);
521 TopAbs_Orientation orv = aVertex.Orientation();
522 if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) {
523 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
525 if (orv==TopAbs_FORWARD)
526 Controlp = C->Value(GC->First());
528 Controlp = C->Value(GC->Last());
530 Controlp.Transform(L.Transformation());
531 aD2=prep.SquareDistance(Controlp);
534 aNewTolerance=sqrt(aD2)+dd;
535 // printf("(Vert,2) Tolerance=%15.10lg\n", aNewTolerance);
536 if (aNewTolerance<aMaxTol)
537 TV->UpdateTolerance(aNewTolerance);
547 //=======================================================================
548 //function : CheckFaceClosed2d
550 //=======================================================================
552 Standard_Boolean TopOpeBRepBuild_Tools::CheckFaceClosed2d(const TopoDS_Face& theFace)
554 Standard_Boolean isClosed = Standard_True;
555 TopExp_Explorer ex(theFace,TopAbs_WIRE);
556 for (; ex.More() && isClosed; ex.Next()) {
557 const TopoDS_Wire& aW = TopoDS::Wire(ex.Current());
558 BRepCheck_Wire aWChk(aW);
559 BRepCheck_Status aStatus = aWChk.Orientation(theFace);
560 if (aStatus != BRepCheck_NoError)
561 isClosed = Standard_False;