0024428: Implementation of LGPL license
[occt.git] / src / BOPTest / BOPTest_TolerCommands.cxx
CommitLineData
b311480e 1// Created on: 2000-03-16
973c2be1 2// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
15#include <BOPTest.ixx>
7fd59977 16#include <stdio.h>
7fd59977 17#include <TCollection_AsciiString.hxx>
18#include <TColStd_IndexedMapOfTransient.hxx>
7fd59977 19#include <TopoDS_Shape.hxx>
20#include <TopoDS_Vertex.hxx>
91322f44 21#include <Draw.hxx>
7fd59977 22#include <DBRep.hxx>
7fd59977 23#include <gp_Pnt2d.hxx>
24
25#include <Geom_Curve.hxx>
26#include <Geom2d_Curve.hxx>
27#include <Geom_Surface.hxx>
28
29#include <TopoDS.hxx>
30#include <TopoDS_Vertex.hxx>
31#include <TopoDS_Edge.hxx>
32#include <TopoDS_Face.hxx>
33
34#include <TopAbs_Orientation.hxx>
35
36#include <TopTools_ListIteratorOfListOfShape.hxx>
37#include <TopTools_ListOfShape.hxx>
38#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
39#include <TopTools_MapOfShape.hxx>
40#include <TopTools_IndexedMapOfShape.hxx>
41
42#include <BRep_TVertex.hxx>
43#include <BRep_TEdge.hxx>
44#include <BRep_ListOfCurveRepresentation.hxx>
45#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
46#include <BRep_CurveRepresentation.hxx>
47#include <BRep_Tool.hxx>
48#include <BRep_Builder.hxx>
49#include <BRep_TFace.hxx>
50
51#include <TopLoc_Location.hxx>
52
53#include <BRepLib.hxx>
54
55#include <TopExp.hxx>
56#include <TopExp_Explorer.hxx>
57
58static
59 Standard_Integer breducetolerance (Draw_Interpretor&, Standard_Integer, const char** );
60static
61 Standard_Integer btolx (Draw_Interpretor&, Standard_Integer, const char** );
62static
63 Standard_Integer bopaddpcs (Draw_Interpretor&, Standard_Integer, const char** );
64//
65static
66 void ProcessVertex(const TopoDS_Vertex&,
4e57c75e 67 const TopTools_ListOfShape&,
68 const TopTools_ListOfShape&);
7fd59977 69static
70 void ProcessEdge(const TopoDS_Edge&, const Standard_Real);
71
72static
73 void ReduceVertexTolerance (const TopoDS_Shape&);
74
75static
76 void ReduceFaceTolerance (const TopoDS_Shape&);
77
78static
79 void ReduceEdgeTolerance (const TopoDS_Shape&, const Standard_Real);
80
81
82//=======================================================================
83//function : TolerCommands
84//purpose :
85//=======================================================================
86 void BOPTest::TolerCommands(Draw_Interpretor& theCommands)
87{
88 static Standard_Boolean done = Standard_False;
89 if (done)
90 return;
91
92 done = Standard_True;
93 // Chapter's name
94 const char* g = "CCR commands";
95 //
96 theCommands.Add("breducetolerance" , "Use >breducetolerance Shape [maxTol=0.01]", __FILE__, breducetolerance, g);
97 theCommands.Add("btolx" , "Use >btolx Shape [minTol=1.e-7]", __FILE__, btolx, g);
98 theCommands.Add("bopaddpcs" , "Use >bopaddpcs Shape" , __FILE__, bopaddpcs, g);
99}
100
101//=======================================================================
102//function : btolx
103//purpose :
104//=======================================================================
105Standard_Integer btolx(Draw_Interpretor& di, Standard_Integer n, const char** a)
106{
107 if (n<2) {
108 di << " Use >btolx Shape [minTol=1.e-7]\n";
109 return 1;
110 }
111
112 TopoDS_Shape aS = DBRep::Get(a[1]);
113
114 if (aS.IsNull()) {
115 di << " Null shape is not allowed \n";
116 return 1;
117 }
118 //
119 Standard_Real aTolEMin=1.e-7;
120 if (n==3) {
91322f44 121 aTolEMin=Draw::Atof(a[2]);
7fd59977 122 }
123 //
124 // Edge Tolerances
125 ReduceEdgeTolerance(aS, aTolEMin);
126 //
127 // Face Tolerances
128 ReduceFaceTolerance(aS);
129 //
130 // Vertex Tolerances
131 ReduceVertexTolerance(aS);
132 //
133 BRepLib::SameParameter(aS, 1.e-7, Standard_True);
134 //
135 DBRep::Set (a[1], aS);
136 return 0;
137}
138//=======================================================================
139//function : ReduceEdgeTolerance
140//purpose :
141//=======================================================================
142void ReduceEdgeTolerance (const TopoDS_Shape& aS, const Standard_Real aTolTreshold)
143{
144 Standard_Integer i, aNbE;
145 TopTools_IndexedMapOfShape aEMap;
146 //
147 TopExp::MapShapes(aS, TopAbs_EDGE, aEMap);
148 //
149 aNbE=aEMap.Extent();
150 for (i=1; i<=aNbE; i++) {
151 const TopoDS_Edge& aE= TopoDS::Edge(aEMap(i));
152
153 ProcessEdge(aE, aTolTreshold);
154 }
155}
156//=======================================================================
157//function : ReduceFaceTolerance
158//purpose :
159//=======================================================================
160void ReduceFaceTolerance (const TopoDS_Shape& aS)
161{
162 Standard_Integer i, j, aNbF, aNbE;
163 Standard_Real aTolE, aTolx, aTolEMin;
164 TopTools_IndexedMapOfShape aFMap, aEMap;
165 //
166 aTolEMin=1.e-7;
167 //
168 TopExp::MapShapes(aS, TopAbs_FACE, aFMap);
169 aNbF=aFMap.Extent();
170 for (i=1; i<=aNbF; i++) {
171 aTolx=1.e6;
172 const TopoDS_Face& aF= TopoDS::Face(aFMap(i));
173 Handle(BRep_TFace)& aTF = *((Handle(BRep_TFace)*)&aF.TShape());
174 //
175 TopExp::MapShapes(aF, TopAbs_EDGE, aEMap);
176 aNbE=aEMap.Extent();
177 for (j=1; j<=aNbE; ++j) {
178 const TopoDS_Edge& aE= TopoDS::Edge(aEMap(j));
179 aTolE =BRep_Tool::Tolerance(aE);
180 if (aTolE<aTolx) {
181 aTolx=aTolE;
182 }
183 }
184 aTolE=(aTolx>aTolEMin) ? aTolx : aTolEMin;
185 aTF->Tolerance(aTolE);
186 }
187}
188//=======================================================================
189//function : ReduceVertexTolerance
190//purpose :
191//=======================================================================
192void ReduceVertexTolerance (const TopoDS_Shape& aS)
193{
194 Standard_Integer i, aNbV;
195 TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap;
196
197 TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
198 TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
199
200 aNbV=aVEMap.Extent();
201 for (i=1; i<=aNbV; i++) {
202 const TopoDS_Vertex& aV= TopoDS::Vertex(aVEMap.FindKey(i));
203 const TopTools_ListOfShape& aLE=aVEMap(i);
204 const TopTools_ListOfShape& aLF=aVFMap.FindFromKey(aV);
205
206 ProcessVertex(aV, aLE, aLF);
207 }
208}
209//=======================================================================
210//function : ProcessEdge
211//purpose :
212//=======================================================================
213void ProcessEdge(const TopoDS_Edge& aE, const Standard_Real aTolTreshold)
214{
215 Standard_Integer i, aNb=23;
216 Standard_Real aTolE, aD2, aTolMax2, aT1, aT2, aT, dT;
217 gp_Pnt aPC3D, aP3D;
218 gp_Pnt2d aPC2D;
219
220 //TopTools_ListIteratorOfListOfShape anIt;// Wng in Gcc 3.0
221 BRep_ListIteratorOfListOfCurveRepresentation itcr;
222 //
223 Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aT1, aT2);
224 if (aC3D.IsNull()) {
225 return;
226 }
227 //
228 dT=(aT2-aT1)/aNb;
229 //
230 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
231 const TopLoc_Location& Eloc = aE.Location();
232 //
233 aTolMax2=-1.e6;
234 const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
235 //
236 itcr.Initialize(aLCR);
237 for (; itcr.More(); itcr.Next()) {
238 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
239 const TopLoc_Location& loc = cr->Location();
240 TopLoc_Location L = (Eloc * loc);//.Predivided(aV.Location());
241 //
242 // 3D-Curve
243 if (cr->IsCurve3D()) {
244 continue;
245 }
246 //
247 // 2D-Curve
248 else if (cr->IsCurveOnSurface()) {
249 const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
250 if (aC2D.IsNull()) {
251 continue;
252 }
253 // Surface
254 const Handle(Geom_Surface)& aS=cr->Surface();
255 //
256 // 2D-point treatment
257 for (i=0; i<=aNb; ++i) {
258 aT=aT1+i*dT;
259 if (i==aNb) {
260 aT=aT2;
261 }
262 aPC3D=aC3D->Value(aT);
263 aPC2D=aC2D->Value(aT);
264 aS->D0(aPC2D.X(), aPC2D.Y(), aP3D);
265 aP3D.Transform(L.Transformation());
266 aD2=aPC3D.SquareDistance(aP3D);
267 if (aD2 > aTolMax2) {
268 aTolMax2=aD2;
269 }
270 }
271 } //if (cr->IsCurveOnSurface())
272 }//for (; itcr.More(); itcr.Next())
273
274 //#########################################################
275 //
276 if (aTolMax2<0.){
277 return;
278 }
279 //
280 aTolE =BRep_Tool::Tolerance(aE);
281 //
282 aTolMax2=sqrt(aTolMax2);
283
284 //printf(" aTolMax=%15.10lf, aTolWas=%15.10lf\n", aTolMax2, aTolE);
285
286 Standard_Real aTolSet;
287 aTolSet=(aTolMax2>aTolTreshold) ? aTolMax2 : aTolTreshold;
288
289 TE->Tolerance(aTolSet);
290}
291//=======================================================================
292//function : ProcessVertex
293//purpose :
294//=======================================================================
295void ProcessVertex(const TopoDS_Vertex& aV,
296 const TopTools_ListOfShape& aLE,
297 const TopTools_ListOfShape& aLF)
298{
299 Standard_Real aTol, aTol2, aD2, aTolMax2, aTolE, aParam;
300 gp_Pnt aPC3D;
301 gp_Pnt2d aPC2D;
302 TopAbs_Orientation anOrV;
303
304 TopTools_ListIteratorOfListOfShape anIt;
305 TopTools_MapOfShape aProcessedEdges;
306 TopExp_Explorer aVExp;
307
308 BRep_ListIteratorOfListOfCurveRepresentation itcr;
309 //
310 aTolMax2=-1.e6;
311 //
312 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape());
313 const gp_Pnt& aPV3D = TV->Pnt();
314 aTol =BRep_Tool::Tolerance(aV);
315 aTol2=aTol*aTol;
316 //
317 anIt.Initialize(aLE);
318 for (; anIt.More(); anIt.Next()) {
319 const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
320 //
321 if (aProcessedEdges.Contains(aE)) {
322 continue;
323 }
324 aProcessedEdges.Add(aE);
325 //
326 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
327 const TopLoc_Location& Eloc = aE.Location();
328 //
329 aVExp.Init(aE, TopAbs_VERTEX);
330 for (; aVExp.More(); aVExp.Next()) {
331 const TopoDS_Vertex& aVx=TopoDS::Vertex(aVExp.Current());
332 //
333 if (!aVx.IsSame(aV)) {
334 continue;
335 }
336 //
337 anOrV=aVx.Orientation();
338 if (!(anOrV==TopAbs_FORWARD || anOrV==TopAbs_REVERSED)) {
339 continue;
340 }
341 //
342 const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
343 itcr.Initialize(aLCR);
344 for (; itcr.More(); itcr.Next()) {
345 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
346 const TopLoc_Location& loc = cr->Location();
347 TopLoc_Location L = (Eloc * loc).Predivided(aV.Location());
348 //
349 // 3D-Curve
350 if (cr->IsCurve3D()) {
351 const Handle(Geom_Curve)& aC3D = cr->Curve3D();
352 //
353 if (aC3D.IsNull()) {
354 continue;
355 }
356 // 3D-point treatment
357 aParam=BRep_Tool::Parameter(aVx, aE);
358 aPC3D= aC3D->Value(aParam);
359 aPC3D.Transform(L.Transformation());
360 aD2=aPV3D.SquareDistance(aPC3D);
361 if (aD2 > aTolMax2) {
362 aTolMax2=aD2;
363 }
364 //
365 }//if (cr->IsCurve3D())
366 //
367 // 2D-Curve
368 else if (cr->IsCurveOnSurface()) {
369 const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
370 if (aC2D.IsNull()) {
371 continue;
372 }
373 // Surface
374 const Handle(Geom_Surface)& aS=cr->Surface();
375 //
376 // 2D-point treatment
377 aParam=BRep_Tool::Parameter(aVx, aE, aS, L);
378 aPC2D=aC2D->Value(aParam);
379 aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D);
380 aPC3D.Transform(L.Transformation());
381 aD2=aPV3D.SquareDistance(aPC3D);
382 if (aD2 > aTolMax2) {
383 aTolMax2=aD2;
384 }
385 } //if (cr->IsCurveOnSurface())
386
387 }//for (; itcr.More(); itcr.Next())
388 }//for (; aVExp.More(); aVExp.Next())
389 }//for (; anIt.More(); anIt.Next())
390 //#########################################################
391 //
392 // Reducing
393 if (aTolMax2<0.){
394 return;
395 }
396 //
397 aTolMax2=sqrt(aTolMax2);
398 if (aTolMax2>aTol) {
399 return;
400 }
401 //
402 aProcessedEdges.Clear();
403 anIt.Initialize(aLE);
404 for (; anIt.More(); anIt.Next()) {
405 const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
406
407 if (aProcessedEdges.Contains(aE)) {
408 continue;
409 }
410 aProcessedEdges.Add(aE);
411
412 aTolE =BRep_Tool::Tolerance(aE);
413 if (aTolMax2 < aTolE) {
414 aTolMax2=aTolE;
415 }
416 }
417 //
418 aProcessedEdges.Clear();
419 anIt.Initialize(aLF);
420 for (; anIt.More(); anIt.Next()) {
421 const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
422
423 if (aProcessedEdges.Contains(aF)) {
424 continue;
425 }
426 aProcessedEdges.Add(aF);
427
428 aTolE =BRep_Tool::Tolerance(aF);
429 if (aTolMax2 < aTolE) {
430 aTolMax2=aTolE;
431 }
432 }
433 //
434 if (aTolMax2>aTol) {
435 return;
436 }
437 //
438 // Update Tolerance
439 TV->Tolerance(aTolMax2);
440}
441//=======================================================================
442//function : breducetolerance
443//purpose :
444//=======================================================================
445Standard_Integer breducetolerance(Draw_Interpretor& di,
446 Standard_Integer n,
447 const char** a)
448{
449 if (n<2) {
450 di << " Use >bupdatetolerance Shape\n";
451 return 1;
452 }
453
454 TopoDS_Shape aS = DBRep::Get(a[1]);
455
456 if (aS.IsNull()) {
457 di << " Null shape is not allowed \n";
458 return 1;
459 }
460 ReduceVertexTolerance(aS);
461 DBRep::Set (a[1], aS);
462
463 return 0;
464}
465//
466//
467static
468 void PreparePCurves(const TopoDS_Shape& aShape, Draw_Interpretor& di);
469
470//=======================================================================
471//function : bopaddpcs
472//purpose : Some Edgesdo not contain P-Curveson Faces to which they belong to.
473// These faces usually based on Geom_Plane surface.
474// To prevent sophisticated treatment the Command "bopaddpcs:
475// adds P-Curves for the edges .
476//=======================================================================
477Standard_Integer bopaddpcs(Draw_Interpretor& di, Standard_Integer n, const char** a)
478{
479 if (n<2) {
480 di << " Use >bopaddpcs Shape\n";
481 return 1;
482 }
483
484 TopoDS_Shape aS = DBRep::Get(a[1]);
485
486 if (aS.IsNull()) {
487 di << " Null shape is not allowed \n";
488 return 1;
489 }
490 //
491 PreparePCurves(aS, di);
492 //
493 DBRep::Set (a[1], aS);
494 return 0;
495}
496
497//=======================================================================
498//function : PreparePCurves
499//purpose :
500//=======================================================================
501void PreparePCurves(const TopoDS_Shape& aShape, Draw_Interpretor& di)
502{
503 Standard_Integer i, aNbE;
504 Standard_Real aTolE, aT1, aT2;
505 TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
506 TopLoc_Location aLoc;
507 Handle(Geom_Curve) aC3D;
508 Handle(Geom2d_Curve) aC2D;
509 BRep_Builder aBB;
510 //
511 TopExp::MapShapesAndAncestors (aShape, TopAbs_EDGE, TopAbs_FACE, aEFMap);
512 //
513 aNbE=aEFMap.Extent();
514 for (i=1; i<=aNbE; ++i) {
515 const TopoDS_Edge& aE=TopoDS::Edge(aEFMap.FindKey(i));
516 //
517 if (BRep_Tool::Degenerated(aE)) {
518 continue;
519 }
520 //
521 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
522 if (aC3D.IsNull()) {
523 continue;
524 }
525 aTolE=BRep_Tool::Tolerance(aE);
526 //
527 const TopTools_ListOfShape& aLF=aEFMap(i);
528 TopTools_ListIteratorOfListOfShape aFIt(aLF);
529 for (; aFIt.More(); aFIt.Next()) {
530 const TopoDS_Face& aF=TopoDS::Face(aFIt.Value());
531 //
532 // Map of surfaces on which the edge lays .
533 TColStd_IndexedMapOfTransient aSCRMap;
534 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
535 const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
536 BRep_ListIteratorOfListOfCurveRepresentation itcr;
537 itcr.Initialize(aLCR);
538 for (; itcr.More(); itcr.Next()) {
539 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
540 //
541 if (cr->IsCurveOnSurface()) {
542 const Handle(Geom_Surface)& aSCR=cr->Surface();
543 aSCRMap.Add(aSCR);
544 }
545 //
546 }
547 //
548 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF, aLoc);
549 if (!aSCRMap.Contains(aS)) {
550 // try to obtain 2D curve
551 aC2D=BRep_Tool::CurveOnSurface(aE, aS, aLoc, aT1, aT2);
552 if (aC2D.IsNull()) {
553 di << " Warning: Can not obtain P-Curve\n";
554 continue;
555 }
556 else {
557 aBB.UpdateEdge(aE, aC2D, aF, aTolE);
558 }
559 }
560 }
561 }
562}