0023765: The result of section operation contains redundant vertex.
[occt.git] / src / Draft / Draft_Modification.cxx
CommitLineData
b311480e 1// Created on: 1994-08-30
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1994-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
23#include <Draft_Modification.ixx>
24
25#include <BRep_Tool.hxx>
26#include <TopLoc_Location.hxx>
27#include <TopExp_Explorer.hxx>
28#include <TopTools_ListIteratorOfListOfShape.hxx>
29
30#include <Geom_Surface.hxx>
31#include <Geom_RectangularTrimmedSurface.hxx>
32#include <Geom_CylindricalSurface.hxx>
33#include <Geom_SphericalSurface.hxx>
34#include <Geom_SurfaceOfLinearExtrusion.hxx>
35#include <Geom_ConicalSurface.hxx>
36#include <Geom_TrimmedCurve.hxx>
37#include <Geom_Circle.hxx>
38#include <Geom_Ellipse.hxx>
39
40#include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
41#include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
42#include <Draft_FaceInfo.hxx>
43#include <Draft_EdgeInfo.hxx>
44#include <Draft_VertexInfo.hxx>
45
46#include <StdFail_NotDone.hxx>
47#include <Standard_ConstructionError.hxx>
48#include <Standard_DomainError.hxx>
49#include <Standard_NoSuchObject.hxx>
50
51#include <gp_Pnt2d.hxx>
52#include <gp_Vec2d.hxx>
53
54#include <TopoDS.hxx>
55#include <TopExp.hxx>
56#include <GeomProjLib.hxx>
57
58#include <Precision.hxx>
59
60#include <BRep_Builder.hxx>
729d84d4 61#include <BRepTools.hxx>
7fd59977 62
63//=======================================================================
64//function : Draft_Modification
65//purpose :
66//=======================================================================
67
68Draft_Modification::Draft_Modification (const TopoDS_Shape& S) :
69 myComp(Standard_False),myShape(S)
70{
71 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEFMap);
72}
73
74
75
76//=======================================================================
77//function : Clear
78//purpose :
79//=======================================================================
80
81void Draft_Modification::Clear ()
82{
83 myComp = Standard_False;
84 myFMap.Clear();
85 myEMap.Clear();
86 myVMap.Clear();
87 myEFMap.Clear();
88 badShape.Nullify();
89 errStat = Draft_NoError;
90}
91
92
93
94//=======================================================================
95//function : Init
96//purpose :
97//=======================================================================
98
99void Draft_Modification::Init(const TopoDS_Shape& S)
100{
101 myShape = S;
102 Clear();
103 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEFMap);
104}
105
106//=======================================================================
107//function : Add
108//purpose :
109//=======================================================================
110
111Standard_Boolean Draft_Modification::Add(const TopoDS_Face& F,
112 const gp_Dir& Direction,
113 const Standard_Real Angle,
114 const gp_Pln& NeutralPlane,
115 const Standard_Boolean Flag)
116{
117 if (!badShape.IsNull()) {
118 Standard_ConstructionError::Raise();
119 }
120
121 if (myComp) {
122 Clear();
123 }
124 curFace = F;
125 return InternalAdd(F,Direction,Angle,NeutralPlane, Flag);
126}
127
128
129//=======================================================================
130//function : Remove
131//purpose :
132//=======================================================================
133
134void Draft_Modification::Remove(const TopoDS_Face& F)
135{
136 if (!myFMap.IsBound(F) || myComp) {
137 Standard_NoSuchObject::Raise();
138 }
139
140 conneF.Clear();
141 TopTools_ListIteratorOfListOfShape ltod;
142
143 curFace = myFMap(F).RootFace();
144 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
145 while (itf.More()) {
146 const TopoDS_Face& theF = itf.Key();
147 if (myFMap(theF).RootFace().IsSame(curFace)) {
148 conneF.Append(theF);
149 if (theF.IsSame(badShape)) {
150 badShape.Nullify();
151 }
152 }
153 itf.Next();
154 }
155
156 ltod.Initialize(conneF);
157 while (ltod.More()) {
158 myFMap.UnBind(TopoDS::Face(ltod.Value()));
159 ltod.Next();
160 }
161
162 conneF.Clear();
163 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
164 while (ite.More()) {
165 const TopoDS_Edge& theE = ite.Key();
166 if (myEMap(theE).RootFace().IsSame(curFace)) {
167 conneF.Append(theE);
168 }
169 ite.Next();
170 }
171 ltod.Initialize(conneF);
172 while (ltod.More()) {
173 myEMap.UnBind(TopoDS::Edge(ltod.Value()));
174 ltod.Next();
175 }
176}
177
178
179//=======================================================================
180//function : IsDone
181//purpose :
182//=======================================================================
183
184Standard_Boolean Draft_Modification::IsDone() const
185{
186 return myComp && badShape.IsNull();
187}
188
189
190//=======================================================================
191//function : Error
192//purpose :
193//=======================================================================
194
195Draft_ErrorStatus Draft_Modification::Error() const
196{
197 return errStat;
198}
199
200
201//=======================================================================
202//function : ProblematicShape
203//purpose :
204//=======================================================================
205
206const TopoDS_Shape& Draft_Modification::ProblematicShape() const
207{
208 return badShape;
209}
210
211
212//=======================================================================
213//function : ConnectedFaces
214//purpose :
215//=======================================================================
216
217const TopTools_ListOfShape & Draft_Modification::ConnectedFaces(const TopoDS_Face& F)
218{
219 if (!myFMap.IsBound(F)) {
220 Standard_NoSuchObject::Raise();
221 }
222 if (!IsDone()) {
223 StdFail_NotDone::Raise();
224 }
225 conneF.Clear();
226 curFace = myFMap(F).RootFace();
227
228 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
229 while (itf.More()) {
230 const TopoDS_Face& theF = itf.Key();
231 if (myFMap(theF).RootFace().IsSame(curFace)) {
232 conneF.Append(theF);
233 }
234 itf.Next();
235 }
236
237 return conneF;
238
239
240}
241
242
243//=======================================================================
244//function : ModifiedFaces
245//purpose :
246//=======================================================================
247
248const TopTools_ListOfShape & Draft_Modification::ModifiedFaces()
249{
250 if (!badShape.IsNull()) {
251 StdFail_NotDone::Raise();
252 }
253 conneF.Clear();
254
255 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
256 while (itf.More()) {
257 const TopoDS_Face& theF = itf.Key();
258 if (!myFMap(theF).RootFace().IsNull()) {
259 conneF.Append(theF);
260 }
261 itf.Next();
262 }
263
264 return conneF;
265
266
267}
268
269
270//=======================================================================
271//function : NewSurface
272//purpose :
273//=======================================================================
274
275Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
276 Handle(Geom_Surface)& S,
277 TopLoc_Location& L,
278 Standard_Real& Tol,
279 Standard_Boolean& RevWires,
280 Standard_Boolean& RevFace)
281{
282 if (!IsDone()) {Standard_DomainError::Raise();}
283
284 if (!myFMap.IsBound(F) || !myFMap(F).NewGeometry()) {
285 return Standard_False;
286 }
287
288 RevWires = Standard_False;
289 RevFace = Standard_False;
290 Tol = BRep_Tool::Tolerance(F);
291
292 S = BRep_Tool::Surface(F,L);
293
294 L.Identity();
295
296 S = myFMap(F).Geometry();
297
298 return Standard_True;
299}
300
301
302//=======================================================================
303//function : NewCurve
304//purpose :
305//=======================================================================
306
307Standard_Boolean Draft_Modification::NewCurve(const TopoDS_Edge& E,
308 Handle(Geom_Curve)& C,
309 TopLoc_Location& L,
310 Standard_Real& Tol)
311{
312 if (!IsDone()) {Standard_DomainError::Raise();}
313
314 if (!myEMap.IsBound(E))
315 return Standard_False;
316
317 const Draft_EdgeInfo& Einf= myEMap(E);
318 if (!myEMap(E).NewGeometry())
319 return Standard_False;
320
321 Tol = Einf.Tolerance();
322 Tol = Max(Tol, BRep_Tool::Tolerance(E));
323 L.Identity();
324 C = myEMap(E).Geometry();
325
326 return Standard_True;
327
328}
329
330
331//=======================================================================
332//function : NewPoint
333//purpose :
334//=======================================================================
335
336Standard_Boolean Draft_Modification::NewPoint(const TopoDS_Vertex& V,
337 gp_Pnt& P,
338 Standard_Real& Tol)
339{
340 if (!IsDone()) {Standard_DomainError::Raise();};
341
342 if (!myVMap.IsBound(V)) {
343 return Standard_False;
344 }
345
346 Tol = BRep_Tool::Tolerance(V);
347 P = myVMap(V).Geometry();
348 return Standard_True;
349}
350
351
352//=======================================================================
353//function : NewCurve2d
354//purpose :
355//=======================================================================
356
357Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
358 const TopoDS_Face& F,
359 const TopoDS_Edge& NewE,
360 const TopoDS_Face&,
361 Handle(Geom2d_Curve)& C,
362 Standard_Real& Tol)
363{
364
365 if (!IsDone()) {Standard_DomainError::Raise();};
366
367 if (!myEMap.IsBound(E)) {
368 return Standard_False;
369 }
370
371 Standard_Real Fp,Lp;
372 BRep_Tool::Range(NewE,Fp,Lp);
373
374 Handle(Geom_Surface) SB = myFMap(F).Geometry();
375
376 const Draft_EdgeInfo& Einf = myEMap(E);
377 if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) {
378 C = Einf.FirstPC();
379 }
380 else if ( Einf.SecondFace().IsSame(F) && !Einf.SecondPC().IsNull()) {
381 C = Einf.SecondPC();
382 }
383 else {
384
385 if (!myEMap(E).NewGeometry()) {
386 Standard_Real Fpi,Lpi;
387 BRep_Tool::Range(E,Fpi,Lpi);
388 if (Fpi <= Fp && Fp <= Lpi && Fpi <= Lp && Lp <= Lpi) {
389 return Standard_False;
390 }
391 }
392
393 Tol = BRep_Tool::Tolerance(E);
394
395 // if (!BRep_Tool::IsClosed(E,F)) {
396 BRep_Tool::Range(NewE,Fp,Lp);
397 Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(myEMap(E).Geometry(),
398 Fp,Lp);
399 Fp = TC->FirstParameter();
400 Lp = TC->LastParameter();
401 BRep_Builder B;
402 B.Range( NewE, Fp, Lp );
403 C = GeomProjLib::Curve2d(TC,Fp, Lp, SB, Tol);
404 }
405
406 Handle(Standard_Type) typs = SB->DynamicType();
407 if (typs == STANDARD_TYPE(Geom_RectangularTrimmedSurface) ) {
408 SB = Handle(Geom_RectangularTrimmedSurface)::DownCast(SB)->BasisSurface();
409 typs = SB->DynamicType();
410 }
411
412 Standard_Boolean JeRecadre = Standard_False;
413 if (typs == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
414 Handle(Geom_Curve) aC =
415 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SB)->BasisCurve();
416 Handle(Standard_Type) typc = aC->DynamicType();
417 if (typc == STANDARD_TYPE(Geom_Circle)) JeRecadre = Standard_True;
418 }
419
420 JeRecadre = JeRecadre ||
421 (typs == STANDARD_TYPE(Geom_CylindricalSurface)) ||
422 (typs == STANDARD_TYPE(Geom_SphericalSurface)) ||
423 (typs == STANDARD_TYPE(Geom_ConicalSurface));
424
425 if ( JeRecadre) {
729d84d4 426 Standard_Boolean bTranslate;
427 Standard_Real aD2, aT1, aT2;
428 gp_Pnt2d PF, NewPF, aP2DT;
429 gp_Vec2d aV2DT, vectra(2.*M_PI,0.);
430 Handle(Geom2d_Curve) aC2DE;
431 //
432 aC2DE=BRep_Tool::CurveOnSurface(E, F, aT1, aT2);
433 //
434 PF=aC2DE->Value(0.5*(aT1+aT2));
435 //
436 NewPF=C->Value(0.5*(Fp+Lp));
437 //
438 aD2=NewPF.SquareDistance(PF);
439 //
440 bTranslate=Standard_False;
441 if (NewPF.Translated(vectra).SquareDistance(PF) < aD2) {
442 aV2DT=vectra;
443 bTranslate=!bTranslate; //True
7fd59977 444 }
729d84d4 445 else if (NewPF.Translated(-vectra).SquareDistance(PF) < aD2) {
446 aV2DT=-vectra;
447 bTranslate=!bTranslate; //True
448 }
449 //
450 if (bTranslate) {
451 C->Translate(aV2DT);
7fd59977 452 }
453 }
7fd59977 454 return Standard_True;
455}
456
457
458//=======================================================================
459//function : NewParameter
460//purpose :
461//=======================================================================
462
463Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
464 const TopoDS_Edge& E,
465 Standard_Real& P,
466 Standard_Real& Tol)
467{
468
469 if (!IsDone()) {Standard_DomainError::Raise();};
470
471 if (!myVMap.IsBound(V)) {
472 return Standard_False;
473 }
474
475 P = myVMap(V).Parameter(E);
476 Handle(Geom_Curve) GC = myEMap(E).Geometry();
477 Handle(Standard_Type) typc = GC->DynamicType();
478 if (typc == STANDARD_TYPE(Geom_TrimmedCurve)) {
479 GC = Handle(Geom_TrimmedCurve)::DownCast(GC);
480 typc = GC->DynamicType();
481 }
482
483 if (GC->IsClosed()) {
484 TopoDS_Vertex FV = TopExp::FirstVertex(E);
485 Standard_Real paramf;
486 if (myVMap.IsBound(FV)) {
487 paramf = myVMap(FV).Parameter(E);
488 }
489 else {
490 paramf = BRep_Tool::Parameter(FV,E);
491 }
492
493 //Patch
494 Standard_Real FirstPar = GC->FirstParameter(), LastPar = GC->LastParameter();
495 Standard_Real pconf = Precision::PConfusion();
496 if (Abs( paramf - LastPar ) <= pconf)
497 {
498 paramf = FirstPar;
499 FV.Orientation(E.Orientation());
500 if (V.IsEqual( FV ))
501 P = paramf;
502 }
503
504 FV.Orientation(E.Orientation());
505 if (!V.IsEqual(FV) && P <= paramf) {
506 if (GC->IsPeriodic()) {
507 P += GC->Period();
508 }
509 else {
510 P = GC->LastParameter();
511 }
512 }
513 }
514
515 Tol = Max (BRep_Tool::Tolerance(V), BRep_Tool::Tolerance(E));
516 return Standard_True;
517}
518
519
520
521//=======================================================================
522//function : Continuity
523//purpose :
524//=======================================================================
525
526GeomAbs_Shape Draft_Modification::Continuity(const TopoDS_Edge& E,
527 const TopoDS_Face& F1,
528 const TopoDS_Face& F2,
529 const TopoDS_Edge&,
530 const TopoDS_Face&,
531 const TopoDS_Face&)
532{
533 return BRep_Tool::Continuity(E,F1,F2);
534}
535
536