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