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); |
8cc2a23a |
152 | Standard_Integer IndToReplace = 0; |
7fd59977 |
153 | while (ltod.More()) { |
8cc2a23a |
154 | IndToReplace = myFMap.FindIndex(TopoDS::Face(ltod.Value())); |
155 | if (IndToReplace) |
156 | { |
157 | Standard_Integer LInd = myFMap.Extent(); |
158 | TopoDS_Face LF = myFMap.FindKey(LInd); |
159 | Draft_FaceInfo LFInfo = myFMap.FindFromIndex(LInd); |
160 | myFMap.RemoveLast(); |
161 | if (IndToReplace != LInd) |
162 | myFMap.Substitute(IndToReplace, LF, LFInfo); |
163 | } |
7fd59977 |
164 | ltod.Next(); |
165 | } |
166 | |
167 | conneF.Clear(); |
8cc2a23a |
168 | for (Standard_Integer i = 1; i <= myEMap.Extent(); i++) |
169 | { |
170 | const TopoDS_Edge& theE = myEMap.FindKey(i); |
171 | if (myEMap.FindFromKey(theE).RootFace().IsSame(curFace)) |
345d3056 |
172 | conneF.Append(theE); |
7fd59977 |
173 | } |
174 | ltod.Initialize(conneF); |
175 | while (ltod.More()) { |
8cc2a23a |
176 | IndToReplace = myFMap.FindIndex(TopoDS::Face(ltod.Value())); |
177 | if (IndToReplace) |
178 | { |
179 | Standard_Integer LInd = myEMap.Extent(); |
180 | TopoDS_Edge LF = myEMap.FindKey(LInd); |
181 | Draft_EdgeInfo LFInfo = myEMap.FindFromIndex(LInd); |
182 | myEMap.RemoveLast(); |
183 | if (IndToReplace != LInd) |
184 | myEMap.Substitute(IndToReplace, LF, LFInfo); |
185 | } |
7fd59977 |
186 | ltod.Next(); |
187 | } |
188 | } |
189 | |
190 | |
191 | //======================================================================= |
192 | //function : IsDone |
193 | //purpose : |
194 | //======================================================================= |
195 | |
196 | Standard_Boolean Draft_Modification::IsDone() const |
197 | { |
198 | return myComp && badShape.IsNull(); |
199 | } |
200 | |
201 | |
202 | //======================================================================= |
203 | //function : Error |
204 | //purpose : |
205 | //======================================================================= |
206 | |
207 | Draft_ErrorStatus Draft_Modification::Error() const |
208 | { |
209 | return errStat; |
210 | } |
211 | |
212 | |
213 | //======================================================================= |
214 | //function : ProblematicShape |
215 | //purpose : |
216 | //======================================================================= |
217 | |
218 | const TopoDS_Shape& Draft_Modification::ProblematicShape() const |
219 | { |
220 | return badShape; |
221 | } |
222 | |
223 | |
224 | //======================================================================= |
225 | //function : ConnectedFaces |
226 | //purpose : |
227 | //======================================================================= |
228 | |
229 | const TopTools_ListOfShape & Draft_Modification::ConnectedFaces(const TopoDS_Face& F) |
230 | { |
8cc2a23a |
231 | if (!myFMap.Contains(F)) { |
9775fa61 |
232 | throw Standard_NoSuchObject(); |
7fd59977 |
233 | } |
234 | if (!IsDone()) { |
9775fa61 |
235 | throw StdFail_NotDone(); |
7fd59977 |
236 | } |
237 | conneF.Clear(); |
8cc2a23a |
238 | curFace = myFMap.FindFromKey(F).RootFace(); |
7fd59977 |
239 | |
8cc2a23a |
240 | for (Standard_Integer i = 1; i <= myFMap.Extent(); i++) |
241 | { |
242 | const TopoDS_Face& theF = myFMap.FindKey(i); |
243 | if (myFMap.FindFromKey(theF).RootFace().IsSame(curFace)) { |
7fd59977 |
244 | conneF.Append(theF); |
245 | } |
7fd59977 |
246 | } |
247 | |
248 | return conneF; |
345d3056 |
249 | |
7fd59977 |
250 | |
251 | } |
252 | |
253 | |
254 | //======================================================================= |
255 | //function : ModifiedFaces |
256 | //purpose : |
257 | //======================================================================= |
258 | |
259 | const TopTools_ListOfShape & Draft_Modification::ModifiedFaces() |
260 | { |
261 | if (!badShape.IsNull()) { |
9775fa61 |
262 | throw StdFail_NotDone(); |
7fd59977 |
263 | } |
264 | conneF.Clear(); |
265 | |
8cc2a23a |
266 | for (Standard_Integer i = 1; i <= myFMap.Extent(); i++) |
267 | { |
268 | const TopoDS_Face& theF = myFMap.FindKey(i); |
269 | if (!myFMap.FindFromKey(theF).RootFace().IsNull()) { |
7fd59977 |
270 | conneF.Append(theF); |
271 | } |
7fd59977 |
272 | } |
273 | |
274 | return conneF; |
345d3056 |
275 | |
7fd59977 |
276 | |
277 | } |
278 | |
279 | |
280 | //======================================================================= |
281 | //function : NewSurface |
282 | //purpose : |
283 | //======================================================================= |
284 | |
285 | Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F, |
345d3056 |
286 | Handle(Geom_Surface)& S, |
287 | TopLoc_Location& L, |
288 | Standard_Real& Tol, |
289 | Standard_Boolean& RevWires, |
290 | Standard_Boolean& RevFace) |
7fd59977 |
291 | { |
9775fa61 |
292 | if (!IsDone()) {throw Standard_DomainError();} |
7fd59977 |
293 | |
8cc2a23a |
294 | if (!myFMap.Contains(F) || !myFMap.FindFromKey(F).NewGeometry()) { |
7fd59977 |
295 | return Standard_False; |
296 | } |
297 | |
298 | RevWires = Standard_False; |
299 | RevFace = Standard_False; |
300 | Tol = BRep_Tool::Tolerance(F); |
301 | |
302 | S = BRep_Tool::Surface(F,L); |
303 | |
304 | L.Identity(); |
305 | |
8cc2a23a |
306 | S = myFMap.FindFromKey(F).Geometry(); |
7fd59977 |
307 | |
308 | return Standard_True; |
309 | } |
345d3056 |
310 | |
7fd59977 |
311 | |
312 | //======================================================================= |
313 | //function : NewCurve |
314 | //purpose : |
315 | //======================================================================= |
316 | |
317 | Standard_Boolean Draft_Modification::NewCurve(const TopoDS_Edge& E, |
345d3056 |
318 | Handle(Geom_Curve)& C, |
319 | TopLoc_Location& L, |
320 | Standard_Real& Tol) |
7fd59977 |
321 | { |
9775fa61 |
322 | if (!IsDone()) {throw Standard_DomainError();} |
7fd59977 |
323 | |
8cc2a23a |
324 | if (!myEMap.Contains(E)) |
7fd59977 |
325 | return Standard_False; |
345d3056 |
326 | |
8cc2a23a |
327 | const Draft_EdgeInfo& Einf= myEMap.FindFromKey(E); |
328 | if (!myEMap.FindFromKey(E).NewGeometry()) |
7fd59977 |
329 | return Standard_False; |
345d3056 |
330 | |
7fd59977 |
331 | Tol = Einf.Tolerance(); |
332 | Tol = Max(Tol, BRep_Tool::Tolerance(E)); |
333 | L.Identity(); |
8cc2a23a |
334 | C = myEMap.FindFromKey(E).Geometry(); |
7fd59977 |
335 | |
336 | return Standard_True; |
337 | |
338 | } |
339 | |
340 | |
341 | //======================================================================= |
342 | //function : NewPoint |
343 | //purpose : |
344 | //======================================================================= |
345 | |
346 | Standard_Boolean Draft_Modification::NewPoint(const TopoDS_Vertex& V, |
345d3056 |
347 | gp_Pnt& P, |
348 | Standard_Real& Tol) |
7fd59977 |
349 | { |
9775fa61 |
350 | if (!IsDone()) {throw Standard_DomainError();}; |
7fd59977 |
351 | |
8cc2a23a |
352 | if (!myVMap.Contains(V)) { |
7fd59977 |
353 | return Standard_False; |
354 | } |
355 | |
356 | Tol = BRep_Tool::Tolerance(V); |
8cc2a23a |
357 | P = myVMap.FindFromKey(V).Geometry(); |
7fd59977 |
358 | return Standard_True; |
359 | } |
360 | |
361 | |
362 | //======================================================================= |
363 | //function : NewCurve2d |
364 | //purpose : |
365 | //======================================================================= |
366 | |
367 | Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E, |
345d3056 |
368 | const TopoDS_Face& F, |
369 | const TopoDS_Edge& NewE, |
370 | const TopoDS_Face&, |
371 | Handle(Geom2d_Curve)& C, |
372 | Standard_Real& Tol) |
7fd59977 |
373 | { |
345d3056 |
374 | |
9775fa61 |
375 | if (!IsDone()) {throw Standard_DomainError();}; |
7fd59977 |
376 | |
8cc2a23a |
377 | if (!myEMap.Contains(E)) { |
7fd59977 |
378 | return Standard_False; |
379 | } |
345d3056 |
380 | |
7fd59977 |
381 | Standard_Real Fp,Lp; |
382 | BRep_Tool::Range(NewE,Fp,Lp); |
345d3056 |
383 | |
8cc2a23a |
384 | Handle(Geom_Surface) SB = myFMap.FindFromKey(F).Geometry(); |
7fd59977 |
385 | |
345d3056 |
386 | Tol = BRep_Tool::Tolerance(E); |
387 | |
8cc2a23a |
388 | const Draft_EdgeInfo& Einf = myEMap.FindFromKey(E); |
7fd59977 |
389 | if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) { |
390 | C = Einf.FirstPC(); |
391 | } |
392 | else if ( Einf.SecondFace().IsSame(F) && !Einf.SecondPC().IsNull()) { |
393 | C = Einf.SecondPC(); |
394 | } |
395 | else { |
345d3056 |
396 | |
8cc2a23a |
397 | if (!myEMap.FindFromKey(E).NewGeometry()) { |
7fd59977 |
398 | Standard_Real Fpi,Lpi; |
399 | BRep_Tool::Range(E,Fpi,Lpi); |
400 | if (Fpi <= Fp && Fp <= Lpi && Fpi <= Lp && Lp <= Lpi) { |
345d3056 |
401 | return Standard_False; |
7fd59977 |
402 | } |
403 | } |
345d3056 |
404 | |
7fd59977 |
405 | // if (!BRep_Tool::IsClosed(E,F)) { |
406 | BRep_Tool::Range(NewE,Fp,Lp); |
8cc2a23a |
407 | Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(myEMap.FindFromKey(E).Geometry(), |
345d3056 |
408 | Fp,Lp); |
7fd59977 |
409 | Fp = TC->FirstParameter(); |
410 | Lp = TC->LastParameter(); |
411 | BRep_Builder B; |
412 | B.Range( NewE, Fp, Lp ); |
413 | C = GeomProjLib::Curve2d(TC,Fp, Lp, SB, Tol); |
414 | } |
415 | |
416 | Handle(Standard_Type) typs = SB->DynamicType(); |
417 | if (typs == STANDARD_TYPE(Geom_RectangularTrimmedSurface) ) { |
418 | SB = Handle(Geom_RectangularTrimmedSurface)::DownCast(SB)->BasisSurface(); |
419 | typs = SB->DynamicType(); |
420 | } |
421 | |
422 | Standard_Boolean JeRecadre = Standard_False; |
423 | if (typs == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) { |
424 | Handle(Geom_Curve) aC = |
425 | Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SB)->BasisCurve(); |
426 | Handle(Standard_Type) typc = aC->DynamicType(); |
427 | if (typc == STANDARD_TYPE(Geom_Circle)) JeRecadre = Standard_True; |
428 | } |
429 | |
430 | JeRecadre = JeRecadre || |
345d3056 |
431 | (typs == STANDARD_TYPE(Geom_CylindricalSurface)) || |
432 | (typs == STANDARD_TYPE(Geom_SphericalSurface)) || |
433 | (typs == STANDARD_TYPE(Geom_ConicalSurface)); |
7fd59977 |
434 | |
435 | if ( JeRecadre) { |
729d84d4 |
436 | Standard_Boolean bTranslate; |
437 | Standard_Real aD2, aT1, aT2; |
438 | gp_Pnt2d PF, NewPF, aP2DT; |
439 | gp_Vec2d aV2DT, vectra(2.*M_PI,0.); |
440 | Handle(Geom2d_Curve) aC2DE; |
441 | // |
442 | aC2DE=BRep_Tool::CurveOnSurface(E, F, aT1, aT2); |
443 | // |
444 | PF=aC2DE->Value(0.5*(aT1+aT2)); |
445 | // |
446 | NewPF=C->Value(0.5*(Fp+Lp)); |
447 | // |
448 | aD2=NewPF.SquareDistance(PF); |
449 | // |
450 | bTranslate=Standard_False; |
451 | if (NewPF.Translated(vectra).SquareDistance(PF) < aD2) { |
452 | aV2DT=vectra; |
453 | bTranslate=!bTranslate; //True |
7fd59977 |
454 | } |
729d84d4 |
455 | else if (NewPF.Translated(-vectra).SquareDistance(PF) < aD2) { |
456 | aV2DT=-vectra; |
457 | bTranslate=!bTranslate; //True |
458 | } |
459 | // |
460 | if (bTranslate) { |
461 | C->Translate(aV2DT); |
7fd59977 |
462 | } |
463 | } |
345d3056 |
464 | // |
465 | Handle(Geom_Curve) aC3d = BRep_Tool::Curve(NewE, Fp, Lp); |
2651bfde |
466 | Tol = BRepTools::EvalAndUpdateTol(NewE,aC3d, C, SB, Fp, Lp); |
7fd59977 |
467 | return Standard_True; |
468 | } |
469 | |
470 | |
471 | //======================================================================= |
472 | //function : NewParameter |
473 | //purpose : |
474 | //======================================================================= |
475 | |
476 | Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V, |
345d3056 |
477 | const TopoDS_Edge& E, |
478 | Standard_Real& P, |
479 | Standard_Real& Tol) |
7fd59977 |
480 | { |
481 | |
9775fa61 |
482 | if (!IsDone()) {throw Standard_DomainError();}; |
7fd59977 |
483 | |
8cc2a23a |
484 | if (!myVMap.Contains(V)) { |
7fd59977 |
485 | return Standard_False; |
486 | } |
487 | |
8cc2a23a |
488 | P = myVMap.ChangeFromKey(V).Parameter(E); |
489 | Handle(Geom_Curve) GC = myEMap.FindFromKey(E).Geometry(); |
7fd59977 |
490 | Handle(Standard_Type) typc = GC->DynamicType(); |
491 | if (typc == STANDARD_TYPE(Geom_TrimmedCurve)) { |
492 | GC = Handle(Geom_TrimmedCurve)::DownCast(GC); |
493 | typc = GC->DynamicType(); |
494 | } |
495 | |
496 | if (GC->IsClosed()) { |
497 | TopoDS_Vertex FV = TopExp::FirstVertex(E); |
498 | Standard_Real paramf; |
8cc2a23a |
499 | if (myVMap.Contains(FV)) { |
500 | paramf = myVMap.ChangeFromKey(FV).Parameter(E); |
7fd59977 |
501 | } |
502 | else { |
503 | paramf = BRep_Tool::Parameter(FV,E); |
504 | } |
505 | |
506 | //Patch |
507 | Standard_Real FirstPar = GC->FirstParameter(), LastPar = GC->LastParameter(); |
508 | Standard_Real pconf = Precision::PConfusion(); |
509 | if (Abs( paramf - LastPar ) <= pconf) |
345d3056 |
510 | { |
511 | paramf = FirstPar; |
512 | FV.Orientation(E.Orientation()); |
513 | if (V.IsEqual( FV )) |
514 | P = paramf; |
515 | } |
7fd59977 |
516 | |
517 | FV.Orientation(E.Orientation()); |
518 | if (!V.IsEqual(FV) && P <= paramf) { |
519 | if (GC->IsPeriodic()) { |
345d3056 |
520 | P += GC->Period(); |
7fd59977 |
521 | } |
522 | else { |
345d3056 |
523 | P = GC->LastParameter(); |
7fd59977 |
524 | } |
525 | } |
526 | } |
345d3056 |
527 | |
7fd59977 |
528 | Tol = Max (BRep_Tool::Tolerance(V), BRep_Tool::Tolerance(E)); |
529 | return Standard_True; |
530 | } |
531 | |
532 | |
533 | |
534 | //======================================================================= |
535 | //function : Continuity |
536 | //purpose : |
537 | //======================================================================= |
538 | |
539 | GeomAbs_Shape Draft_Modification::Continuity(const TopoDS_Edge& E, |
345d3056 |
540 | const TopoDS_Face& F1, |
541 | const TopoDS_Face& F2, |
542 | const TopoDS_Edge&, |
543 | const TopoDS_Face&, |
544 | const TopoDS_Face&) |
7fd59977 |
545 | { |
546 | return BRep_Tool::Continuity(E,F1,F2); |
547 | } |
345d3056 |
548 | |
7fd59977 |
549 | |