b311480e |
1 | // Created on: 1995-02-22 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1995-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> |
19 | #include <BRep_GCurve.hxx> |
20 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
21 | #include <BRep_TEdge.hxx> |
22 | #include <BRep_Tool.hxx> |
23 | #include <BRepAdaptor_Curve.hxx> |
24 | #include <BRepAdaptor_Curve2d.hxx> |
7fd59977 |
25 | #include <BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal.hxx> |
42cf5bc1 |
26 | #include <BRepFill_DataMapOfShapeSequenceOfReal.hxx> |
27 | #include <BRepLib.hxx> |
28 | #include <BRepLib_MakeVertex.hxx> |
29 | #include <BRepOffsetAPI_DraftAngle.hxx> |
7fd59977 |
30 | #include <BRepOffsetAPI_SequenceOfSequenceOfReal.hxx> |
31 | #include <BRepOffsetAPI_SequenceOfSequenceOfShape.hxx> |
42cf5bc1 |
32 | #include <BRepTools.hxx> |
7fd59977 |
33 | #include <BRepTools_Substitution.hxx> |
42cf5bc1 |
34 | #include <Draft_Modification.hxx> |
35 | #include <Geom2d_Curve.hxx> |
36 | #include <Geom_Surface.hxx> |
37 | #include <gp_Dir.hxx> |
38 | #include <gp_Pln.hxx> |
39 | #include <Precision.hxx> |
40 | #include <Standard_ConstructionError.hxx> |
41 | #include <Standard_NoSuchObject.hxx> |
42 | #include <Standard_NullObject.hxx> |
43 | #include <StdFail_NotDone.hxx> |
44 | #include <TColgp_SequenceOfPnt.hxx> |
45 | #include <TColStd_SequenceOfReal.hxx> |
7fd59977 |
46 | #include <TopExp.hxx> |
42cf5bc1 |
47 | #include <TopExp_Explorer.hxx> |
48 | #include <TopLoc_Location.hxx> |
49 | #include <TopoDS.hxx> |
50 | #include <TopoDS_Face.hxx> |
51 | #include <TopoDS_Iterator.hxx> |
52 | #include <TopoDS_Shape.hxx> |
7fd59977 |
53 | #include <TopoDS_Wire.hxx> |
42cf5bc1 |
54 | #include <TopOpeBRep_EdgesIntersector.hxx> |
55 | #include <TopOpeBRep_Point2d.hxx> |
56 | #include <TopTools_DataMapOfShapeSequenceOfShape.hxx> |
57 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
58 | #include <TopTools_SequenceOfShape.hxx> |
7fd59977 |
59 | |
60 | //======================================================================= |
61 | //function : BRepOffsetAPI_DraftAngle |
62 | //purpose : |
63 | //======================================================================= |
7fd59977 |
64 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle () {} |
65 | |
66 | |
67 | //======================================================================= |
68 | //function : BRepOffsetAPI_DraftAngle |
69 | //purpose : |
70 | //======================================================================= |
71 | |
72 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle (const TopoDS_Shape& S) |
73 | { |
74 | myInitialShape = S; |
75 | myModification = new Draft_Modification(S); |
76 | } |
77 | |
78 | |
79 | //======================================================================= |
80 | //function : Clear |
81 | //purpose : |
82 | //======================================================================= |
83 | |
84 | void BRepOffsetAPI_DraftAngle::Clear () |
85 | { |
86 | if (!myModification.IsNull()) { |
c5f3a425 |
87 | Handle(Draft_Modification)::DownCast (myModification)->Clear(); |
7fd59977 |
88 | } |
89 | } |
90 | |
91 | |
92 | //======================================================================= |
93 | //function : Init |
94 | //purpose : |
95 | //======================================================================= |
96 | |
97 | void BRepOffsetAPI_DraftAngle::Init (const TopoDS_Shape& S) |
98 | { |
99 | myInitialShape = S; |
100 | NotDone(); |
101 | if (!myModification.IsNull()) { |
c5f3a425 |
102 | Handle(Draft_Modification)::DownCast (myModification)->Init(S); |
7fd59977 |
103 | } |
104 | else { |
105 | myModification = new Draft_Modification(S); |
106 | } |
107 | } |
108 | |
109 | |
110 | //======================================================================= |
111 | //function : Add |
112 | //purpose : |
113 | //======================================================================= |
114 | |
115 | void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F, |
116 | const gp_Dir& D, |
117 | const Standard_Real Angle, |
118 | const gp_Pln& Plane, |
119 | const Standard_Boolean Flag) |
120 | { |
121 | // POP-DPF : protection |
122 | if ( Abs(Angle) <= 1.e-04 ) |
123 | return; |
124 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
125 | Handle(Draft_Modification)::DownCast (myModification)->Add(F,D,Angle,Plane, Flag); |
7fd59977 |
126 | } |
127 | |
128 | |
129 | //======================================================================= |
130 | //function : AddDone |
131 | //purpose : |
132 | //======================================================================= |
133 | |
134 | Standard_Boolean BRepOffsetAPI_DraftAngle::AddDone () const |
135 | { |
136 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
137 | return Handle(Draft_Modification)::DownCast (myModification) |
7fd59977 |
138 | ->ProblematicShape().IsNull(); |
139 | } |
140 | |
141 | |
142 | //======================================================================= |
143 | //function : Remove |
144 | //purpose : |
145 | //======================================================================= |
146 | |
147 | void BRepOffsetAPI_DraftAngle::Remove(const TopoDS_Face& F) |
148 | { |
149 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
150 | Handle(Draft_Modification)::DownCast (myModification)->Remove(F); |
7fd59977 |
151 | } |
152 | |
153 | |
154 | //======================================================================= |
155 | //function : ProblematicShape |
156 | //purpose : |
157 | //======================================================================= |
158 | |
159 | const TopoDS_Shape& BRepOffsetAPI_DraftAngle::ProblematicShape () const |
160 | { |
161 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
162 | return Handle(Draft_Modification)::DownCast (myModification)->ProblematicShape(); |
7fd59977 |
163 | } |
164 | |
165 | |
166 | //======================================================================= |
167 | //function : ErrorStatus |
168 | //purpose : |
169 | //======================================================================= |
170 | |
171 | Draft_ErrorStatus BRepOffsetAPI_DraftAngle::Status () const |
172 | { |
173 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
174 | return Handle(Draft_Modification)::DownCast (myModification)->Error(); |
7fd59977 |
175 | } |
176 | |
177 | |
178 | //======================================================================= |
179 | //function : ConnectedFaces |
180 | //purpose : |
181 | //======================================================================= |
182 | |
183 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces |
184 | (const TopoDS_Face& F) const |
185 | { |
186 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
187 | return Handle(Draft_Modification)::DownCast (myModification)->ConnectedFaces(F); |
7fd59977 |
188 | } |
189 | |
190 | |
191 | //======================================================================= |
192 | //function : ModifiedFaces |
193 | //purpose : |
194 | //======================================================================= |
195 | |
196 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ModifiedFaces() const |
197 | { |
198 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
199 | return Handle(Draft_Modification)::DownCast (myModification)->ModifiedFaces(); |
7fd59977 |
200 | } |
201 | |
202 | //======================================================================= |
203 | //function : ModifiedFaces |
204 | //purpose : |
205 | //======================================================================= |
206 | |
207 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Shape& S) |
208 | { |
209 | myGenerated.Clear(); |
210 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
211 | Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification); |
7fd59977 |
212 | |
213 | if (S.ShapeType() == TopAbs_FACE) { |
214 | Handle(Geom_Surface) Surf; |
215 | TopLoc_Location L; |
216 | Standard_Real Tol; |
217 | Standard_Boolean RW,RF; |
218 | if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
219 | myGenerated.Append(ModifiedShape (S)); |
220 | |
221 | } |
222 | } |
223 | return myGenerated; |
224 | } |
225 | |
226 | //======================================================================= |
227 | //function : ModifiedFaces |
228 | //purpose : |
229 | //======================================================================= |
230 | |
231 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shape& S) |
232 | { |
233 | myGenerated.Clear(); |
234 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
235 | Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification); |
7fd59977 |
236 | |
237 | if (S.ShapeType() == TopAbs_FACE) { |
238 | Handle(Geom_Surface) Surf; |
239 | TopLoc_Location L; |
240 | Standard_Real Tol; |
241 | Standard_Boolean RW,RF; |
242 | |
243 | if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
244 | // Ce n est pas une generation => peut etre une modif |
245 | myGenerated.Append(ModifiedShape (S)); |
246 | if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) { |
247 | myGenerated.Clear(); |
248 | } |
249 | } |
250 | } |
251 | return myGenerated; |
252 | } |
253 | |
345d3056 |
254 | //======================================================================= |
255 | //function : ModifiedShape |
256 | //purpose : |
257 | //======================================================================= |
258 | |
259 | TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape |
260 | (const TopoDS_Shape& S) const |
261 | { |
262 | if(S.ShapeType() == TopAbs_VERTEX) |
263 | { |
264 | if(myVtxToReplace.IsBound(S)) |
265 | { |
266 | return myVtxToReplace(S); |
267 | } |
268 | } |
269 | return myModifier.ModifiedShape(S); |
270 | } |
7fd59977 |
271 | |
272 | //======================================================================= |
273 | //function : Build |
274 | //purpose : |
275 | //======================================================================= |
276 | |
277 | void BRepOffsetAPI_DraftAngle::Build() |
278 | { |
c5f3a425 |
279 | Handle(Draft_Modification)::DownCast (myModification)->Perform(); |
280 | if (!Handle(Draft_Modification)::DownCast (myModification)->IsDone()) { |
7fd59977 |
281 | NotDone(); |
282 | } |
283 | else { |
284 | DoModif(myInitialShape); |
7fd59977 |
285 | CorrectWires(); |
345d3056 |
286 | CorrectVertexTol(); |
7fd59977 |
287 | } |
288 | } |
289 | |
290 | //======================================================================= |
291 | //function : CorrectWires |
292 | //purpose : |
293 | //======================================================================= |
294 | |
295 | void BRepOffsetAPI_DraftAngle::CorrectWires() |
296 | { |
297 | Standard_Real TolInter = 1.e-7; |
298 | Standard_Integer i, j, k; |
299 | |
300 | TopTools_SequenceOfShape Eseq; |
301 | TopTools_SequenceOfShape Wseq; |
302 | TopTools_SequenceOfShape Fseq; |
303 | TopoDS_Shape CurEdge, CurWire, CurFace; |
304 | TopoDS_Iterator wit, eit; |
305 | |
306 | TopExp_Explorer fexp( myShape, TopAbs_FACE ); |
307 | for (; fexp.More(); fexp.Next()) |
345d3056 |
308 | { |
309 | CurFace = fexp.Current(); |
310 | wit.Initialize( CurFace ); |
311 | for (; wit.More(); wit.Next()) |
7fd59977 |
312 | { |
345d3056 |
313 | CurWire = wit.Value(); |
314 | TopTools_MapOfShape emap; |
315 | eit.Initialize( CurWire ); |
316 | for (; eit.More(); eit.Next()) |
317 | emap.Add( eit.Value() ); |
318 | TopTools_MapIteratorOfMapOfShape mapit( emap ); |
319 | for (; mapit.More(); mapit.Next()) |
320 | { |
321 | CurEdge = mapit.Key(); |
322 | if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) )) |
323 | { |
324 | Eseq.Append( CurEdge ); |
325 | Wseq.Append( CurWire ); |
326 | Fseq.Append( CurFace ); |
327 | } |
328 | } |
7fd59977 |
329 | } |
345d3056 |
330 | } |
7fd59977 |
331 | |
332 | BRepFill_DataMapOfShapeSequenceOfReal Emap; |
333 | |
334 | TopTools_SequenceOfShape NonSeam; |
335 | TopTools_SequenceOfShape NonSeamWires; |
336 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsNonSeam; |
337 | BRepOffsetAPI_SequenceOfSequenceOfShape Seam; |
338 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsSeam; |
339 | |
340 | TopTools_DataMapOfShapeShape WFmap; |
341 | TopTools_DataMapOfShapeListOfShape WWmap; |
342 | for (i = 1; i <= Eseq.Length(); i++) |
345d3056 |
343 | { |
344 | CurEdge = Eseq(i); |
345 | CurWire = Wseq(i); |
346 | CurFace = Fseq(i); |
347 | wit.Initialize( CurFace ); |
348 | for (; wit.More(); wit.Next()) |
7fd59977 |
349 | { |
345d3056 |
350 | TopoDS_Shape aWire = wit.Value(); |
351 | if (! aWire.IsSame( CurWire )) |
352 | { |
353 | TColgp_SequenceOfPnt pts; |
354 | TopTools_SequenceOfShape edges; |
355 | TColStd_SequenceOfReal pars; |
356 | Standard_Boolean Wadd = Standard_False; |
357 | eit.Initialize( aWire ); |
358 | for (; eit.More(); eit.Next()) |
359 | { |
360 | TopoDS_Shape anEdge = eit.Value(); |
361 | TopOpeBRep_EdgesIntersector EInter; |
362 | EInter.SetFaces( CurFace, CurFace ); |
363 | EInter.ForceTolerances( TolInter, TolInter ); |
364 | EInter.Perform( CurEdge, anEdge ); |
365 | if (EInter.IsEmpty()) |
366 | { |
367 | EInter.Perform( CurEdge.Reversed(), anEdge ); |
368 | if (EInter.IsEmpty()) |
369 | continue; |
370 | } |
371 | Wadd = Standard_True; |
372 | if (! WFmap.IsBound( aWire )) |
373 | WFmap.Bind( aWire, CurFace ); |
374 | Standard_Integer ind = 0; |
375 | for (j = 1; j <= NonSeam.Length(); j++) |
376 | if (anEdge.IsSame( NonSeam(j) )) |
377 | { |
378 | ind = j; |
379 | break; |
380 | } |
381 | if (ind == 0) |
382 | { |
383 | NonSeam.Append( anEdge ); |
384 | NonSeamWires.Append( aWire ); |
385 | ind = NonSeam.Length(); |
386 | TColStd_SequenceOfReal emptyseq1, emptyseq2; |
387 | TopTools_SequenceOfShape emptyedgeseq; |
388 | ParsNonSeam.Append( emptyseq1 ); |
389 | Seam.Append( emptyedgeseq ); |
390 | ParsSeam.Append( emptyseq2 ); |
391 | } |
392 | if (! Emap.IsBound( CurEdge )) |
393 | { |
394 | TColStd_SequenceOfReal emptyseq; |
395 | Emap.Bind( CurEdge, emptyseq ); |
396 | } |
397 | EInter.InitPoint(); |
398 | for (; EInter.MorePoint(); EInter.NextPoint()) |
399 | { |
400 | const TopOpeBRep_Point2d& bp = EInter.Point(); |
401 | if (bp.IsVertex(2)) |
402 | { |
403 | gp_Pnt Pnt = bp.Value(); |
404 | Standard_Integer ied = 0; |
405 | for (j = 1; j <= pts.Length(); j++) |
406 | if (Pnt.IsEqual( pts(j), Precision::Confusion() )) |
407 | { |
408 | ied = j; |
409 | break; |
410 | } |
411 | if (ied == 0) |
412 | { |
413 | pts.Append( Pnt ); |
414 | edges.Append( anEdge ); |
415 | pars.Append( bp.Parameter(2) ); |
416 | Emap(CurEdge).Append( bp.Parameter(1) ); |
417 | ParsNonSeam(ind).Append( bp.Parameter(2) ); |
418 | Seam(ind).Append( CurEdge ); |
419 | ParsSeam(ind).Append( bp.Parameter(1) ); |
420 | } |
421 | /* |
422 | else |
423 | { |
424 | Standard_Real ParOnSeam = bp.Parameter(1); |
425 | Standard_Real Par1 = pars(ied); |
426 | Standard_Real Par2 = bp.Parameter(2); |
427 | BRepAdaptor_Curve2d SeamCurve( CurEdge, CurFace ); |
428 | BRepAdaptor_Curve2d Curve1( edges(ied), CurFace ); |
429 | BRepAdaptor_Curve2d Curve2( anEdge. CurFace ); |
430 | gp_Pnt2d P2d; |
431 | gp_Vec2d SeamDer, Der1, Der2; |
432 | //SeamCurve->D1( ParOnSeam, P2d, SeamDer ); |
433 | //Curve1->D1( Par1, P2d, Der1 ); |
434 | //Curve2->D1( Par2, P2d, Der2 ); |
435 | Standard_Real Crossed1 = SeamDer ^ Der1; |
436 | Standard_Real Crossed2 = SeamDer ^ Der2; |
437 | //if (Crossed1 > 0 |
438 | } |
439 | */ |
440 | } |
441 | else // ! bp.IsVertex(2) |
442 | { |
443 | //Temporary the case of tangency is not implemented |
444 | Emap(CurEdge).Append( bp.Parameter(1) ); |
445 | ParsNonSeam(ind).Append( bp.Parameter(2) ); |
446 | Seam(ind).Append( CurEdge ); |
447 | ParsSeam(ind).Append( bp.Parameter(1) ); |
448 | } |
449 | } //for (; EInter.MorePoint(); EInter.NextPoint()) |
450 | } //for (; eit.More(); eit.Next()) |
451 | if (Wadd) |
452 | { |
453 | if (! WWmap.IsBound( CurWire )) |
454 | { |
455 | TopTools_ListOfShape emptylist; |
456 | WWmap.Bind( CurWire, emptylist ); |
457 | } |
458 | WWmap(CurWire).Append( aWire ); |
459 | } |
460 | } //if (! aWire.IsSame( CurWire )) |
461 | } //for (; wit.More(); wit.Next()) |
462 | } //for (i = 1; i <= Eseq.Length(); i++) |
7fd59977 |
463 | |
464 | //Sorting |
465 | for (i = 1; i <= NonSeam.Length(); i++) |
466 | for (j = 1; j < ParsNonSeam(i).Length(); j++) |
467 | for (k = j+1; k <= ParsNonSeam(i).Length(); k++) |
345d3056 |
468 | if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j)) |
469 | { |
470 | Standard_Real temp = ParsNonSeam(i)(j); |
471 | ParsNonSeam(i)(j) = ParsNonSeam(i)(k); |
472 | ParsNonSeam(i)(k) = temp; |
473 | TopoDS_Shape tmp = Seam(i)(j); |
474 | Seam(i)(j) = Seam(i)(k); |
475 | Seam(i)(k) = tmp; |
476 | temp = ParsSeam(i)(j); |
477 | ParsSeam(i)(j) = ParsSeam(i)(k); |
478 | ParsSeam(i)(k) = temp; |
479 | } |
480 | BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap ); |
481 | for (; iter.More(); iter.Next()) |
482 | { |
483 | TColStd_SequenceOfReal Seq; |
484 | Seq = iter.Value(); |
485 | for (i = 1; i < Seq.Length(); i++) |
486 | for (j = i+1; j <= Seq.Length(); j++) |
487 | if (Seq(j) < Seq(i)) |
488 | { |
489 | Standard_Real temp = Seq(i); |
490 | Seq(i) = Seq(j); |
491 | Seq(j) = temp; |
492 | } |
493 | Emap( iter.Key() ) = Seq; |
494 | } |
495 | BRepFill_DataMapOfShapeSequenceOfReal EPmap; |
496 | TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam |
497 | TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it |
498 | iter.Initialize( Emap ); |
499 | for (; iter.More(); iter.Next()) |
500 | { |
501 | TColStd_SequenceOfReal parseq; |
502 | EPmap.Bind( iter.Key(), parseq ); |
503 | TopTools_SequenceOfShape shapeseq; |
504 | EVmap.Bind( iter.Key(), shapeseq ); |
505 | TopTools_SequenceOfShape shapeseq2; |
506 | EWmap.Bind( iter.Key(), shapeseq2 ); |
507 | } |
508 | |
509 | //Reconstruction of non-seam edges |
510 | BRepTools_Substitution aSub; |
511 | BRep_Builder BB; |
512 | for (i = 1; i <= NonSeam.Length(); i++) |
513 | { |
514 | TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) ); |
515 | TopTools_ListOfShape NewEdges; |
516 | TopoDS_Edge NewE; |
517 | TopoDS_Vertex Vfirst, Vlast; |
518 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
519 | Standard_Real par, FirstPar, LastPar; |
520 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
521 | Standard_Integer firstind = 1; |
522 | par = ParsNonSeam(i)(1); |
523 | TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) ); |
524 | //Find the face |
525 | for (j = 1; j <= Eseq.Length(); j++) |
526 | if (SeamEdge.IsSame( Eseq(j) )) |
527 | break; |
528 | TopoDS_Face theFace = TopoDS::Face( Fseq(j) ); |
529 | TopLoc_Location L; |
530 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L ); |
531 | if (Abs(par-FirstPar) <= Precision::Confusion()) |
532 | { |
533 | BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) ); |
534 | EPmap( SeamEdge ).Append( ParsSeam(i)(1) ); |
535 | EVmap( SeamEdge ).Append( Vfirst ); |
536 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
537 | firstind = 2; |
538 | } |
539 | Standard_Real prevpar = FirstPar; |
540 | TopoDS_Vertex PrevV = Vfirst; |
541 | for (j = firstind; j <= ParsNonSeam(i).Length(); j++) |
542 | { |
543 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
544 | NewE = TopoDS::Edge( aLocalShape ); |
545 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
546 | TopoDS_Vertex NewV; |
547 | par = ParsNonSeam(i)(j); |
548 | BB.Range( NewE, prevpar, par ); |
549 | SeamEdge = TopoDS::Edge( Seam(i)(j) ); |
550 | if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion()) |
551 | { |
552 | NewV = Vlast; |
553 | if (firstind == 2 && j == 2) |
554 | { |
555 | BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) ); |
556 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
557 | EVmap( SeamEdge ).Append( Vlast ); |
558 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
559 | break; |
560 | } |
561 | } |
562 | else |
563 | { |
564 | BRepAdaptor_Curve bcur( NewE ); |
565 | gp_Pnt Point = bcur.Value( par ); |
566 | NewV = BRepLib_MakeVertex( Point ); |
567 | BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() ); |
568 | } |
569 | BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() ); |
570 | NewE.Orientation( TopAbs_FORWARD ); |
571 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
572 | BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) ); |
573 | |
574 | NewEdges.Append( NewE ); |
575 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
576 | EVmap( SeamEdge ).Append( NewV ); |
577 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
578 | |
579 | prevpar = par; |
580 | PrevV = NewV; |
581 | } |
582 | //The last edge |
583 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
584 | NewE = TopoDS::Edge( aLocalShape ); |
585 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
586 | par = LastPar; |
587 | if (Abs(prevpar-par) > Precision::Confusion()) |
588 | { |
589 | BB.Range( NewE, prevpar, par ); |
590 | NewE.Orientation( TopAbs_FORWARD ); |
591 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
592 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
593 | NewEdges.Append( NewE ); |
594 | } |
595 | |
596 | //Substitute anEdge by NewEdges |
597 | aSub.Substitute( anEdge, NewEdges ); |
598 | } |
599 | |
600 | //Sorting of EPmap and EVmap and removing repeating points from them |
601 | iter.Initialize( EPmap ); |
602 | for (; iter.More(); iter.Next()) |
603 | { |
604 | TColStd_SequenceOfReal Seq; |
605 | Seq = iter.Value(); |
606 | TopTools_SequenceOfShape SeqShape; |
607 | SeqShape = EVmap( iter.Key() ); |
608 | TopTools_SequenceOfShape SeqShape2; |
609 | SeqShape2 = EWmap( iter.Key() ); |
610 | for (i = 1; i < Seq.Length(); i++) |
611 | for (j = i+1; j <= Seq.Length(); j++) |
612 | if (Seq(j) < Seq(i)) |
613 | { |
614 | Standard_Real temp = Seq(i); |
615 | Seq(i) = Seq(j); |
616 | Seq(j) = temp; |
617 | TopoDS_Shape tmp = SeqShape(i); |
618 | SeqShape(i) = SeqShape(j); |
619 | SeqShape(j) = tmp; |
620 | tmp = SeqShape2(i); |
621 | SeqShape2(i) = SeqShape2(j); |
622 | SeqShape2(j) = tmp; |
623 | } |
624 | EPmap( iter.Key() ) = Seq; |
625 | EVmap( iter.Key() ) = SeqShape; |
626 | EWmap( iter.Key() ) = SeqShape2; |
627 | } |
628 | iter.Initialize( EPmap ); |
629 | for (; iter.More(); iter.Next()) |
630 | { |
631 | TColStd_SequenceOfReal Seq; |
632 | Seq = iter.Value(); |
633 | TopTools_SequenceOfShape SeqShape; |
634 | SeqShape = EVmap( iter.Key() ); |
635 | TopTools_SequenceOfShape SeqShape2; |
636 | SeqShape2 = EWmap( iter.Key() ); |
637 | Standard_Boolean remove = Standard_True; |
638 | while (remove) |
639 | { |
640 | remove = Standard_False; |
641 | for (i = 1; i < Seq.Length(); i++) |
642 | if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion()) |
643 | { |
644 | Seq.Remove(i+1); |
645 | SeqShape.Remove(i+1); |
646 | SeqShape2.Remove(i+1); |
647 | remove = Standard_True; |
648 | } |
649 | } |
650 | EPmap( iter.Key() ) = Seq; |
651 | EVmap( iter.Key() ) = SeqShape; |
652 | EWmap( iter.Key() ) = SeqShape2; |
653 | } |
654 | |
655 | //Reconstruction of seam edges |
656 | TopTools_DataMapOfShapeShape VEmap; |
657 | iter.Initialize( Emap ); |
658 | for (; iter.More(); iter.Next()) |
659 | { |
660 | TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() ); |
661 | Standard_Boolean onepoint = Standard_False; |
662 | TopTools_ListOfShape NewEdges; |
663 | TColStd_SequenceOfReal Seq; |
664 | Seq = iter.Value(); |
665 | TColStd_SequenceOfReal Seq2; |
666 | Seq2 = EPmap( anEdge ); |
667 | TopTools_SequenceOfShape SeqVer; |
668 | SeqVer = EVmap( anEdge ); |
669 | TopTools_SequenceOfShape SeqWire; |
670 | SeqWire = EWmap( anEdge ); |
671 | TopoDS_Vertex Vfirst, Vlast; |
672 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
673 | Standard_Real fpar, lpar, FirstPar, LastPar; |
674 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
675 | fpar = FirstPar; |
676 | lpar = Seq(1); |
677 | TopoDS_Edge NewE; |
678 | Standard_Integer firstind = 1; |
679 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
680 | { |
681 | firstind = 2; |
682 | fpar = Seq(1); |
683 | lpar = Seq(2); |
684 | } |
685 | else |
686 | { |
687 | if (Seq.Length()%2 != 0) |
688 | { |
689 | VEmap.Bind( Vfirst, anEdge ); |
690 | firstind = 2; |
691 | fpar = Seq(1); |
692 | if (Seq.Length() > 2) |
693 | lpar = Seq(2); |
694 | else |
695 | onepoint = Standard_True; |
696 | } |
697 | } |
698 | if (!onepoint) |
699 | { |
700 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
701 | NewE = TopoDS::Edge( aLocalShape ); |
702 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
703 | BB.Range( NewE, fpar, lpar ); |
704 | NewE.Orientation( TopAbs_FORWARD ); |
705 | if (firstind == 1) |
706 | { |
707 | BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) ); |
708 | aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED); |
709 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
710 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) ); |
711 | } |
712 | else |
713 | { |
714 | aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD); |
715 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
716 | aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED); |
717 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
718 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) ); |
719 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) ); |
720 | } |
721 | NewEdges.Append( NewE ); |
722 | |
723 | firstind++; |
724 | for (i = firstind; i < Seq.Length(); i += 2) |
725 | { |
726 | aLocalShape = anEdge.EmptyCopied(); |
727 | NewE = TopoDS::Edge( aLocalShape ); |
728 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
729 | fpar = Seq(i); |
730 | lpar = Seq(i+1); |
731 | BB.Range( NewE, fpar, lpar ); |
732 | //Find vertices |
733 | for (j = 1; j <= Seq2.Length(); j++) |
734 | if (Abs(fpar-Seq2(j)) <= Precision::Confusion()) |
735 | break; |
736 | NewE.Orientation( TopAbs_FORWARD ); |
737 | TopoDS_Shape aLocalShapeCur = SeqVer(j).Oriented(TopAbs_FORWARD); |
738 | BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur) ); |
739 | aLocalShapeCur = SeqVer(j+1).Oriented(TopAbs_REVERSED); |
740 | BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur ) ); |
741 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) ); |
742 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) ); |
743 | NewEdges.Append( NewE ); |
744 | } |
745 | } |
746 | |
747 | i = Seq.Length(); |
748 | fpar = Seq(i); |
749 | lpar = LastPar; |
750 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
751 | continue; |
752 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
753 | NewE = TopoDS::Edge( aLocalShape ); |
754 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
755 | BB.Range( NewE, fpar, lpar ); |
756 | NewE.Orientation( TopAbs_FORWARD ); |
757 | aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD); |
758 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
759 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) ); |
760 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
761 | NewEdges.Append( NewE ); |
762 | |
763 | //Substitute anEdge by NewEdges |
764 | aSub.Substitute( anEdge, NewEdges ); |
765 | } |
766 | |
767 | //Removing edges connected with missing extremities of seam edges |
768 | TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap ); |
769 | for (; itve.More(); itve.Next()) |
770 | { |
771 | TopoDS_Shape V = itve.Key(); |
772 | TopoDS_Shape E = itve.Value(); |
773 | TopoDS_Shape W; |
774 | for (i = 1; i <= Eseq.Length(); i++) |
775 | if (E.IsSame( Eseq(i) )) |
776 | { |
777 | W = Wseq(i); |
778 | break; |
779 | } |
780 | TopoDS_Shape Etoremove; |
781 | eit.Initialize( W ); |
782 | for (; eit.More(); eit.Next()) |
783 | { |
784 | TopoDS_Edge CurE = TopoDS::Edge( eit.Value() ); |
785 | if (CurE.IsSame( E )) |
786 | continue; |
787 | TopoDS_Vertex Vfirst, Vlast; |
788 | TopExp::Vertices( CurE, Vfirst, Vlast ); |
789 | if (Vfirst.IsSame( V ) || Vlast.IsSame( V )) |
790 | { |
791 | Etoremove = CurE; |
792 | break; |
793 | } |
794 | } |
795 | if (! Etoremove.IsNull()) |
796 | { |
797 | W.Free( Standard_True ); |
798 | BB.Remove( W, Etoremove ); |
799 | } |
800 | } |
801 | |
802 | aSub.Build( myShape ); |
803 | if (aSub.IsCopied( myShape )) |
804 | { |
805 | const TopTools_ListOfShape& listSh = aSub.Copy( myShape ); |
806 | if (! listSh.IsEmpty()) |
807 | myShape = listSh.First(); |
808 | } |
809 | |
810 | //Reconstruction of wires |
811 | TopTools_ListOfShape theCopy; |
812 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap ); |
813 | for (; itww.More(); itww.Next()) |
814 | { |
815 | CurWire = itww.Key(); |
816 | theCopy = aSub.Copy( CurWire ); |
817 | CurWire = theCopy.First(); |
818 | CurWire.Free( Standard_True ); |
819 | TopTools_ListIteratorOfListOfShape itl( itww.Value() ); |
820 | for (; itl.More(); itl.Next()) |
821 | { |
822 | TopoDS_Shape aWire = itl.Value(); |
823 | CurFace = WFmap( aWire ); |
824 | theCopy = aSub.Copy( aWire ); |
825 | aWire = theCopy.First(); |
826 | //Adjusting period |
827 | TopLoc_Location L; |
828 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L ); |
829 | eit.Initialize( aWire ); |
830 | for (; eit.More(); eit.Next()) |
831 | { |
832 | TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() ); |
833 | gp_Pnt2d Pfirst, Plast, Pmid; |
834 | BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast ); |
835 | BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) ); |
836 | Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. ); |
837 | gp_Vec2d offset; |
838 | Standard_Boolean translate = Standard_False; |
839 | if (Pfirst.X()-2.*M_PI > Precision::Confusion() || |
840 | Plast.X()-2.*M_PI > Precision::Confusion() || |
841 | Pmid.X()-2.*M_PI > Precision::Confusion()) |
842 | { |
843 | offset.SetCoord( -2.*M_PI, 0 ); |
844 | translate = Standard_True; |
845 | } |
846 | if (Pfirst.X() < -Precision::Confusion() || |
847 | Plast.X() < -Precision::Confusion() || |
848 | Pmid.X() < -Precision::Confusion()) |
849 | { |
850 | offset.SetCoord( 2.*M_PI, 0 ); |
851 | translate = Standard_True; |
852 | } |
853 | if (translate) |
854 | { |
855 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape()); |
856 | BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() ); |
857 | Handle(BRep_GCurve) GC; |
858 | |
859 | for (; itcr.More(); itcr.Next()) |
860 | { |
861 | GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
862 | if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L )) |
863 | { |
864 | Handle(Geom2d_Curve) PC = GC->PCurve(); |
865 | PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) ); |
866 | GC->PCurve( PC ); |
867 | TE->ChangeCurves().Remove( itcr ); |
868 | TE->ChangeCurves().Append( GC ); |
869 | break; |
870 | } |
871 | } |
872 | } |
873 | } |
874 | /////////////////// |
875 | eit.Initialize( aWire, Standard_False ); |
876 | for (; eit.More(); eit.Next()) |
877 | { |
878 | TopoDS_Shape anEdge = eit.Value(); |
879 | BB.Add( CurWire, anEdge ); |
880 | } |
881 | if (aSub.IsCopied( CurFace )) |
882 | { |
883 | theCopy = aSub.Copy( CurFace ); |
884 | CurFace = theCopy.First(); |
885 | } |
886 | CurFace.Free( Standard_True ); |
887 | BB.Remove( CurFace, aWire ); |
888 | } |
889 | } |
890 | } |
891 | //======================================================================= |
892 | //function : CorrectVertexTol |
893 | //purpose : |
894 | //======================================================================= |
7fd59977 |
895 | |
345d3056 |
896 | void BRepOffsetAPI_DraftAngle::CorrectVertexTol() |
897 | { |
898 | TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges; |
899 | TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE); |
900 | for(; anExp.More(); anExp.Next()) |
901 | { |
902 | anInitEdges.Add(anExp.Current()); |
903 | TopoDS_Iterator anIter(anExp.Current()); |
904 | for(; anIter.More(); anIter.Next()) |
7fd59977 |
905 | { |
345d3056 |
906 | anInitVertices.Add(anIter.Value()); |
7fd59977 |
907 | } |
345d3056 |
908 | } |
909 | // |
910 | |
911 | BRep_Builder aBB; |
912 | myVtxToReplace.Clear(); |
913 | anExp.Init(myShape, TopAbs_EDGE); |
914 | for(; anExp.More(); anExp.Next()) |
915 | { |
916 | const TopoDS_Shape& anE = anExp.Current(); |
917 | //Skip old (not modified) edges |
918 | if(anInitEdges.Contains(anE)) |
919 | continue; |
920 | // |
921 | //Skip processed edges |
922 | if(aNewEdges.Contains(anE)) |
923 | continue; |
924 | // |
925 | aNewEdges.Add(anE); |
926 | // |
927 | Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE)); |
928 | TopoDS_Iterator anIter(anE); |
929 | for(; anIter.More(); anIter.Next()) |
7fd59977 |
930 | { |
345d3056 |
931 | const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value()); |
932 | if(anInitVertices.Contains(aVtx)) |
933 | { |
934 | if(myVtxToReplace.IsBound(aVtx)) |
935 | { |
936 | aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol)); |
937 | } |
938 | else |
939 | { |
940 | Standard_Real aVTol = BRep_Tool::Tolerance(aVtx); |
941 | if(aVTol < anETol) |
942 | { |
943 | TopoDS_Vertex aNewVtx; |
944 | gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx); |
945 | aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol)); |
946 | myVtxToReplace.Bind(aVtx, aNewVtx); |
947 | } |
948 | } |
949 | } |
7fd59977 |
950 | else |
345d3056 |
951 | { |
952 | aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol)); |
953 | } |
7fd59977 |
954 | } |
345d3056 |
955 | } |
956 | // |
957 | if(myVtxToReplace.IsEmpty()) |
958 | { |
959 | return; |
960 | } |
961 | // |
962 | BRepTools_Substitution aSub; |
963 | TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace); |
964 | for(; anIter.More(); anIter.Next()) |
965 | { |
966 | TopTools_ListOfShape aSubVtx; |
967 | aSubVtx.Append(anIter.Value()); |
968 | aSub.Substitute(anIter.Key(), aSubVtx); |
969 | } |
7fd59977 |
970 | aSub.Build( myShape ); |
971 | if (aSub.IsCopied( myShape )) |
345d3056 |
972 | { |
973 | const TopTools_ListOfShape& listSh = aSub.Copy( myShape ); |
974 | if (! listSh.IsEmpty()) |
975 | myShape = listSh.First(); |
976 | } |
977 | // |
7fd59977 |
978 | } |