0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_Tools_1.cxx
CommitLineData
b311480e 1// Created on: 2000-02-11
2// Created by: Peter KURNEV
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#include <TopOpeBRepBuild_Tools.ixx>
17
18
19#include <TopTools_IndexedMapOfShape.hxx>
20#include <TopExp.hxx>
21#include <TopExp_Explorer.hxx>
22
23#include <TopoDS.hxx>
24#include <TopoDS_Edge.hxx>
25#include <TopoDS_Vertex.hxx>
26#include <TopoDS_Face.hxx>
27
28#include <TopLoc_Location.hxx>
29
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>
39
40#include <Geom_Curve.hxx>
41#include <Geom_Surface.hxx>
42#include <Geom_Plane.hxx>
43#include <Geom_TrimmedCurve.hxx>
44
45#include <GeomAdaptor_Curve.hxx>
46#include <GeomAdaptor_HCurve.hxx>
47#include <GeomAdaptor_HSurface.hxx>
48
49#include <Geom2d_Curve.hxx>
50
51#include <Geom2dAdaptor_HCurve.hxx>
52#include <Geom_RectangularTrimmedSurface.hxx>
53#include <Geom2dAdaptor.hxx>
54#include <GeomProjLib.hxx>
55
56#include <gp_Pnt.hxx>
57
58#include <Adaptor3d_HCurve.hxx>
59#include <Adaptor3d_CurveOnSurface.hxx>
60#include <Adaptor3d_HCurveOnSurface.hxx>
61
62#include <ProjLib_ProjectedCurve.hxx>
63#include <Extrema_LocateExtPC.hxx>
64#include <BRepCheck_Wire.hxx>
65
66static
67 void CheckEdge (const TopoDS_Edge& E,
68 const Standard_Real aMaxTol);
69static
70 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
71 const TopoDS_Face& S,
72 const Standard_Real aMaxTol);
73static
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);
79
80//=======================================================================
81// Function : CorrectTolerances
82// purpose :
83//=======================================================================
84 void TopOpeBRepBuild_Tools::CorrectTolerances(const TopoDS_Shape& aShape,
85 const Standard_Real aMaxTol)
86{
87 TopOpeBRepBuild_Tools::CorrectPointOnCurve(aShape, aMaxTol);
88 TopOpeBRepBuild_Tools::CorrectCurveOnSurface(aShape, aMaxTol);
89}
90
91//=======================================================================
92// Function : CorrectPointOnCurve
93// purpose :
94//=======================================================================
95 void TopOpeBRepBuild_Tools::CorrectPointOnCurve(const TopoDS_Shape& S,
96 const Standard_Real aMaxTol)
97{
98 Standard_Integer i, aNb;
99 TopTools_IndexedMapOfShape Edges;
100 TopExp::MapShapes (S, TopAbs_EDGE, Edges);
101 aNb=Edges.Extent();
102 for (i=1; i<=aNb; i++) {
103 const TopoDS_Edge& E= TopoDS::Edge(Edges(i));
104 CheckEdge(E, aMaxTol);
105 }
106}
107
108//=======================================================================
109// Function : CorrectCurveOnSurface
110// purpose :
111//=======================================================================
112 void TopOpeBRepBuild_Tools::CorrectCurveOnSurface(const TopoDS_Shape& S,
113 const Standard_Real aMaxTol)
114{
115 Standard_Integer i, aNbFaces, j, aNbEdges;
116 TopTools_IndexedMapOfShape Faces;
117 TopExp::MapShapes (S, TopAbs_FACE, Faces);
118
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);
128 }
129 }
130}
131
132//=======================================================================
133// Function : CorrectEdgeTolerance
134// purpose : Correct tolerances for Edge
135//=======================================================================
136void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
d3f26155 137 const TopoDS_Face& S,
138 const Standard_Real aMaxTol)
7fd59977 139{
140 //
141 // 1. Minimum of conditions to Perform
142 Handle (BRep_CurveRepresentation) myCref;
143 Handle (Adaptor3d_HCurve) myHCurve;
144
145 myCref.Nullify();
146
147 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
148 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
149 Standard_Boolean Degenerated, SameParameter, SameRange;
150
151 Standard_Integer unique = 0;
152
153 Degenerated = TE->Degenerated();
154 SameParameter = TE->SameParameter();
155 SameRange = TE->SameRange();
156
157 if (!SameRange && SameParameter) {
158 return;
159 }
160
161 while (itcr.More()) {
162 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
163 if (cr->IsCurve3D()) {
164 unique++;
165 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
d3f26155 166 myCref = cr;
7fd59977 167 }
168 }
169 itcr.Next();
170 }
171
172 if (unique==0) {
173 return;//...No3DCurve
174 }
175 if (unique>1) {
176 return;//...Multiple3DCurve;
177 }
178
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()) {
d3f26155 184 myCref = cr;
185 break;
7fd59977 186 }
187 itcr.Next();
188 }
189 }
190
191 else if (!myCref.IsNull() && Degenerated){
192 return ;//...InvalidDegeneratedFlag;
193 }
194
195 if (!myCref.IsNull()) {
c5f3a425 196 Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref));
7fd59977 197 Standard_Real First,Last;
198 GCref->Range(First,Last);
199 if (Last<=First) {
200 myCref.Nullify();
201 return ;//InvalidRange;
202 }
203
204 else {
205 if (myCref->IsCurve3D()) {
d3f26155 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);
7fd59977 210 }
211 else { // curve on surface
d3f26155 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);
7fd59977 219 }
220 }
221 }
222
223 //===============================================
224 // 2. Tolerances in InContext
225 {
226 if (myCref.IsNull())
227 return;
228 Standard_Boolean ok=Standard_True;
229
230 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
231 Standard_Real aNewTol=Tol;
232
233 Standard_Real First = myHCurve->FirstParameter();
234 Standard_Real Last = myHCurve->LastParameter();
235
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());
7fd59977 241 Standard_Boolean pcurvefound = Standard_False;
242
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)) {
d3f26155 247 pcurvefound = Standard_True;
c5f3a425 248 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
d3f26155 249 Standard_Real f,l;
250 GC->Range(f,l);
251 if (SameRange && (f != First || l != Last)) {
252 return ;//BRepCheck_InvalidSameRangeFlag;
253 }
254
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);
262 if (ok) {
263 // printf("(Edge,1) Tolerance=%15.10lg\n", aNewTol);
264 if (aNewTol<aMaxTol)
265 TE->UpdateTolerance(aNewTol);
266 }
267 if (cr->IsCurveOnClosedSurface()) {
268 // checkclosed = Standard_True;
269 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
270 ACS.Load(GAHS); // sans doute inutile
271 ACS.Load(GHPC); // meme remarque...
272 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
273 if (ok) {
274 if (aNewTol<aMaxTol)
275 TE->UpdateTolerance(aNewTol);
276 }
7fd59977 277 }
7fd59977 278 }
279 itcr.Next();
280 }
281
282 if (!pcurvefound) {
283 Handle(Geom_Plane) P;
284 Handle(Standard_Type) styp = Su->DynamicType();
285 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
d3f26155 286 P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface)::
287 DownCast(Su)->BasisSurface());
7fd59977 288 }
289 else {
d3f26155 290 P = Handle(Geom_Plane)::DownCast(Su);
7fd59977 291 }
292 if (P.IsNull()) { // not a plane
d3f26155 293 return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface);
7fd59977 294 }
d3f26155 295 else
296 { // on fait la projection a la volee, comme BRep_Tool
297 P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation()));
298 //on projette Cref sur ce plan
299 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
300
301 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
302 GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
303 Handle(Geom_Curve) C3d = Gac.Curve();
304 Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane
305 (new Geom_TrimmedCurve(C3d,First,Last), P, P->Position().Direction(), Standard_True);
306
307 Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
308
309 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
310 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
311 Handle(Geom2dAdaptor_HCurve) GHPC =
312 new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter());
313
314 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
315
316 ok = Validate(myHCurve->Curve(),ACS,
317 Tol,Standard_True, aNewTol); // voir dub...
318 if (ok)
319 {
320 if (aNewTol<aMaxTol)
321 TE->UpdateTolerance(aNewTol);
322 }
7fd59977 323 }
7fd59977 324 }//end of if (!pcurvefound) {
325 } // end of 2. Tolerances in InContext
326
327}
328
329#define NCONTROL 23
330//=======================================================================
331//function : Validate
332//purpose :
333//=======================================================================
334Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
335 const Adaptor3d_Curve& Other,
336 const Standard_Real Tol,
337 const Standard_Boolean SameParameter,
338 Standard_Real& aNewTolerance)
339{
340 Standard_Real First, Last, MaxDistance, aD;
341
342 First = CRef.FirstParameter();
343 Last = CRef.LastParameter();
344 MaxDistance = Tol*Tol;
345
346 Standard_Integer i, aNC1=NCONTROL-1;
347
348 Standard_Boolean aFlag=Standard_False;
349 Standard_Boolean proj = (!SameParameter ||
350 First != Other.FirstParameter() ||
351 Last != Other.LastParameter());
352 //
353 // 1.
354 if (!proj) {
355 for (i = 0; i < NCONTROL; i++) {
356 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
357 gp_Pnt pref = CRef.Value(prm);
358 gp_Pnt pother = Other.Value(prm);
359
360 aD=pref.SquareDistance(pother);
361
362 if (aD > MaxDistance) {
363 MaxDistance=aD;
364 aFlag=Standard_True;
365 }
366 }
367 }
368
369 //
370 // 2.
371 else {
372 Extrema_LocateExtPC refd,otherd;
373 Standard_Real OFirst, OLast;
374 OFirst = Other.FirstParameter();
375 OLast = Other.LastParameter();
376
377 gp_Pnt pd = CRef.Value(First);
378 gp_Pnt pdo = Other.Value(OFirst);
379
380 aD = pd.SquareDistance(pdo);
381 if (aD > MaxDistance) {
382 MaxDistance=aD;
383 aFlag=Standard_True;
384 }
385
386 pd = CRef.Value(Last);
387 pdo = Other.Value(OLast);
388 aD = pd.SquareDistance(pdo);
389 if (aD > MaxDistance) {
390 MaxDistance=aD;
391 aFlag=Standard_True;
392 }
393
394 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
395 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
396
397 for (i = 2; i< aNC1; i++) {
398 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
399 gp_Pnt pref = CRef.Value(rprm);
400
401 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
402 gp_Pnt pother = Other.Value(oprm);
403
404 refd.Perform(pother,rprm);
405 if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) {
406 if (refd.IsDone()) {
407 aD=refd.SquareDistance();
408 if (aD > MaxDistance) {
409 aFlag=Standard_True;
410 MaxDistance=aD;
411 }
412 }
413 }
414
415 otherd.Perform(pref,oprm);
416 if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) {
417
418 if (otherd.IsDone()) {
419 aD=otherd.SquareDistance();
420 if (aD > MaxDistance) {
421 aFlag=Standard_True;
422 MaxDistance=aD;
423 }
424 }
425 }
426 }
427 }
428
429 if (aFlag) {
430 aD=sqrt (MaxDistance);
431 aNewTolerance=aD*1.05;
432 }
433
434 return aFlag;
435
436}
437
438//=======================================================================
439// Function : CheckEdge
440// purpose : Correct tolerances for Vertices on Edge
441//=======================================================================
442void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol)
443{
444 TopoDS_Edge E=Ed;
445 E.Orientation(TopAbs_FORWARD);
446
447 gp_Pnt Controlp;
448
449 TopExp_Explorer aVExp;
450 aVExp.Init(E, TopAbs_VERTEX);
451 for (; aVExp.More(); aVExp.Next()) {
452 TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current());
453
454 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape());
455 const gp_Pnt& prep = TV->Pnt();
456
457 Standard_Real Tol, aD2, aNewTolerance, dd;
458
459 Tol =BRep_Tool::Tolerance(aVertex);
460 Tol = Max(Tol, BRep_Tool::Tolerance(E));
461 dd=0.1*Tol;
462 Tol*=Tol;
463
464 const TopLoc_Location& Eloc = E.Location();
465 BRep_ListIteratorOfListOfPointRepresentation itpr;
466
467 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
468 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
469 while (itcr.More()) {
470 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
471 const TopLoc_Location& loc = cr->Location();
472 TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location());
473
474 if (cr->IsCurve3D()) {
d3f26155 475 const Handle(Geom_Curve)& C = cr->Curve3D();
476 if (!C.IsNull()) {
477 itpr.Initialize(TV->Points());
478 while (itpr.More()) {
479 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
480 if (pr->IsPointOnCurve(C,L)) {
481 Controlp = C->Value(pr->Parameter());
482 Controlp.Transform(L.Transformation());
483 aD2=prep.SquareDistance(Controlp);
484 if (aD2 > Tol) {
485 aNewTolerance=sqrt(aD2)+dd;
486 if (aNewTolerance<aMaxTol)
487 TV->UpdateTolerance(aNewTolerance);
488 }
489 }
490 itpr.Next();
491 }
492
493 TopAbs_Orientation orv = aVertex.Orientation();
494 if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) {
c5f3a425 495 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
d3f26155 496
497 if (orv==TopAbs_FORWARD)
498 Controlp = C->Value(GC->First());
499 else
500 Controlp = C->Value(GC->Last());
501
502 Controlp.Transform(L.Transformation());
503 aD2=prep.SquareDistance(Controlp);
504
505 if (aD2 > Tol) {
506 aNewTolerance=sqrt(aD2)+dd;
507 if (aNewTolerance<aMaxTol)
508 TV->UpdateTolerance(aNewTolerance);
509 }
510 }
511 }
7fd59977 512 }
513 itcr.Next();
514 }
515 }
516}
517
518//=======================================================================
519//function : CheckFaceClosed2d
520//purpose :
521//=======================================================================
522
523Standard_Boolean TopOpeBRepBuild_Tools::CheckFaceClosed2d(const TopoDS_Face& theFace)
524{
525 Standard_Boolean isClosed = Standard_True;
526 TopExp_Explorer ex(theFace,TopAbs_WIRE);
527 for (; ex.More() && isClosed; ex.Next()) {
528 const TopoDS_Wire& aW = TopoDS::Wire(ex.Current());
529 BRepCheck_Wire aWChk(aW);
530 BRepCheck_Status aStatus = aWChk.Orientation(theFace);
531 if (aStatus != BRepCheck_NoError)
532 isClosed = Standard_False;
533 }
534 return isClosed;
535}