b311480e |
1 | // Created on: 1999-04-15 |
2 | // Created by: Roman LYGIN |
3 | // Copyright (c) 1999-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 | // gka 23.06.99 S4208: using tool SU_TransferParameter |
22 | // pdn 13.07.99 synchronizing splitting values on 3d curve and pcurve |
23 | // abv 14.07.99 dealing with edges without 3d curve |
24 | // svv 10.01.00 porting on DEC |
25 | |
26 | #include <ShapeUpgrade_WireDivide.ixx> |
27 | #include <ShapeUpgrade.hxx> |
28 | #include <BRep_Tool.hxx> |
29 | #include <BRep_Builder.hxx> |
30 | #include <BRepLib_MakeFace.hxx> |
31 | #include <BRepLib_MakeWire.hxx> |
32 | #include <TopoDS.hxx> |
33 | #include <TopoDS_Vertex.hxx> |
34 | #include <TopoDS_Edge.hxx> |
35 | #include <TopoDS_Iterator.hxx> |
36 | #include <ShapeBuild_Edge.hxx> |
37 | #include <ShapeAnalysis_Edge.hxx> |
38 | #include <Precision.hxx> |
39 | #include <TopExp.hxx> |
40 | #include <TopExp_Explorer.hxx> |
41 | #include <TColStd_HSequenceOfReal.hxx> |
42 | #include <TColGeom_HArray1OfCurve.hxx> |
43 | #include <TColGeom2d_HArray1OfCurve.hxx> |
44 | #include <gp_Pnt.hxx> |
45 | #include <Geom_Curve.hxx> |
46 | #include <Geom2d_Curve.hxx> |
47 | #include <ShapeExtend.hxx> |
48 | #include <TColStd_Array1OfBoolean.hxx> |
49 | #include <ShapeBuild_ReShape.hxx> |
50 | #include <ShapeAnalysis_TransferParametersProj.hxx> |
51 | #include <ShapeUpgrade_FixSmallCurves.hxx> |
52 | #include <TopTools_SequenceOfShape.hxx> |
53 | #include <TColStd_SequenceOfReal.hxx> |
54 | #include <GeomAdaptor_HSurface.hxx> |
55 | #include <Geom2dAdaptor_HCurve.hxx> |
56 | #include <ShapeAnalysis_Curve.hxx> |
57 | #include <Adaptor3d_CurveOnSurface.hxx> |
58 | |
59 | //======================================================================= |
60 | //function : ShapeUpgrade_WireDivide |
61 | //purpose : |
62 | //======================================================================= |
63 | |
64 | ShapeUpgrade_WireDivide::ShapeUpgrade_WireDivide(): |
65 | ShapeUpgrade_Tool(), myStatus(0) |
66 | { |
67 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide"<<endl; |
68 | mySplitCurve3dTool = new ShapeUpgrade_SplitCurve3d; |
69 | mySplitCurve2dTool = new ShapeUpgrade_SplitCurve2d; |
70 | myTransferParamTool = new ShapeAnalysis_TransferParametersProj; |
71 | myEdgeMode = 2; |
72 | myFixSmallCurveTool = new ShapeUpgrade_FixSmallCurves; |
73 | myEdgeDivide = new ShapeUpgrade_EdgeDivide; |
74 | } |
75 | |
76 | //======================================================================= |
77 | //function : Init |
78 | //purpose : |
79 | //======================================================================= |
80 | |
81 | void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W, |
82 | const TopoDS_Face& F) |
83 | { |
84 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Face"<<endl; |
85 | myWire = W; |
86 | myFace = F; |
87 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
88 | } |
89 | |
90 | //======================================================================= |
91 | //function : Init |
92 | //purpose : |
93 | //======================================================================= |
94 | |
95 | void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W, |
96 | const Handle(Geom_Surface)& S) |
97 | { |
98 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Surface "<<endl; |
99 | myWire = W; |
1c72dff6 |
100 | BRepLib_MakeFace mkf(S, Precision::Confusion()); |
7fd59977 |
101 | myFace = mkf.Face(); |
102 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
103 | } |
104 | |
105 | //======================================================================= |
106 | //function : Load |
107 | //purpose : |
108 | //======================================================================= |
109 | |
110 | void ShapeUpgrade_WireDivide::Load(const TopoDS_Wire& W) |
111 | { |
112 | myWire = W; |
113 | } |
114 | |
115 | //======================================================================= |
116 | //function : Load |
117 | //purpose : |
118 | //======================================================================= |
119 | |
120 | void ShapeUpgrade_WireDivide::Load(const TopoDS_Edge& E) |
121 | { |
122 | BRepLib_MakeWire MakeWire (E); |
123 | if (MakeWire.IsDone()) |
124 | Load (MakeWire.Wire()); |
125 | } |
126 | |
127 | //======================================================================= |
128 | //function : SetFace |
129 | //purpose : |
130 | //======================================================================= |
131 | |
132 | void ShapeUpgrade_WireDivide::SetFace(const TopoDS_Face& F) |
133 | { |
134 | myFace = F; |
135 | } |
136 | |
137 | //======================================================================= |
138 | //function : SetSurface |
139 | //purpose : |
140 | //======================================================================= |
141 | |
142 | void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S) |
143 | { |
1c72dff6 |
144 | BRepLib_MakeFace mkf(S, Precision::Confusion()); |
7fd59977 |
145 | myFace = mkf.Face(); |
146 | } |
147 | |
148 | //======================================================================= |
149 | //function : SetSurface |
150 | //purpose : |
151 | //======================================================================= |
152 | |
153 | void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S, |
154 | const TopLoc_Location& L) |
155 | { |
156 | BRep_Builder B; |
157 | B.MakeFace(myFace,S,L,Precision::Confusion()); |
158 | } |
159 | |
160 | //======================================================================= |
161 | //function : Perform |
162 | //purpose : |
163 | //======================================================================= |
164 | |
165 | static void CorrectSplitValues(const Handle(TColStd_HSequenceOfReal) orig3d, |
166 | const Handle(TColStd_HSequenceOfReal) orig2d, |
167 | Handle(TColStd_HSequenceOfReal) new2d, |
168 | Handle(TColStd_HSequenceOfReal) new3d) |
169 | { |
170 | Standard_Real preci = Precision::PConfusion(); |
171 | Standard_Integer len3d = orig3d->Length(); |
172 | Standard_Integer len2d = orig2d->Length(); |
173 | TColStd_Array1OfBoolean fixNew2d (1, len3d); |
174 | fixNew2d.Init (Standard_False); |
175 | TColStd_Array1OfBoolean fixNew3d (1, len2d); |
176 | fixNew3d.Init (Standard_False); |
177 | Standard_Real Last3d = orig3d->Value(len3d); |
178 | Standard_Real Last2d = orig2d->Value(len2d); |
179 | |
180 | Standard_Integer i;// svv #1 |
181 | for( i = 1; i <= len3d ; i++) { |
182 | Standard_Real par = new2d->Value(i); |
183 | Standard_Integer index = 0; |
184 | for(Standard_Integer j = 1; j <= len2d && !index; j++) |
185 | if(Abs(par-orig2d->Value(j)) < preci) |
186 | index = j; |
187 | if(index&&!fixNew3d(index)) { |
188 | Standard_Real newPar = orig2d->Value(index); |
189 | new2d->SetValue(i,newPar); |
190 | fixNew2d(i) = Standard_True; |
191 | Standard_Real newPar3d = orig3d->Value(i); |
192 | new3d->SetValue(index,newPar3d); |
193 | fixNew3d(index) = Standard_True; |
194 | } |
195 | } |
196 | |
197 | for(i = 1; i <= len2d ; i++) { |
198 | Standard_Real par = new3d->Value(i); |
199 | Standard_Integer index = 0; |
200 | for(Standard_Integer j = 1; j <= len3d && !index; j++) |
201 | if(Abs(par-orig3d->Value(j)) < preci) |
202 | index = j; |
203 | if(index&&!fixNew2d(index)) { |
204 | Standard_Real newPar = orig3d->Value(index); |
205 | new3d->SetValue(i,newPar); |
206 | fixNew3d(i) = Standard_True; |
207 | Standard_Real newPar2d = orig2d->Value(i); |
208 | new2d->SetValue(index,newPar2d); |
209 | fixNew2d(index) = Standard_True; |
210 | } |
211 | } |
212 | |
213 | Standard_Real dpreci = 2* preci; |
214 | for(i = 1; i < len3d; i++) { |
215 | Standard_Real dist = new2d->Value(i+1) - new2d->Value(i); |
216 | if(dist < preci) { |
217 | if(fixNew2d(i+1)) { |
218 | //changing |
219 | Standard_Real tmp = new2d->Value(i+1); |
220 | new2d->SetValue(i+1,new2d->Value(i)+dpreci); |
221 | new2d->SetValue(i,tmp); |
222 | fixNew2d(i) = Standard_True; |
223 | fixNew2d(i+1) = Standard_False; |
224 | } |
225 | else |
226 | new2d->SetValue(i+1,new2d->Value(i)+dpreci); |
227 | } |
228 | } |
229 | if(new2d->Value(len3d) > Last3d) { |
230 | Standard_Integer ind; // svv #1 |
231 | for( ind = len3d; ind > 1 && !fixNew2d(ind); ind--); |
232 | Standard_Real lastFix = new2d->Value(ind); |
233 | for(i = len3d; i >= ind; i--) { |
234 | new2d->SetValue(i,lastFix); |
235 | lastFix-=dpreci; |
236 | } |
237 | } |
238 | |
239 | for(i = 1; i < len2d; i++) { |
240 | Standard_Real dist = new3d->Value(i+1) - new3d->Value(i); |
241 | if(dist < preci) { |
242 | if(fixNew3d(i+1)) { |
243 | //changing |
244 | Standard_Real tmp = new3d->Value(i+1); |
245 | new3d->SetValue(i+1,new3d->Value(i)+dpreci); |
246 | new3d->SetValue(i,tmp); |
247 | fixNew3d(i) = Standard_True; |
248 | fixNew3d(i+1) = Standard_False; |
249 | } |
250 | else |
251 | new3d->SetValue(i+1,new3d->Value(i)+dpreci); |
252 | } |
253 | } |
254 | if(new3d->Value(len2d) > Last2d) { |
255 | Standard_Integer ind; // svv #1 |
256 | for(ind = len2d; ind > 1 && !fixNew3d(ind); ind--); |
257 | Standard_Real lastFix = new3d->Value(ind); |
258 | for(i = len2d; i >= ind; i--) { |
259 | new3d->SetValue(i,lastFix); |
260 | lastFix-=dpreci; |
261 | } |
262 | } |
263 | } |
264 | |
265 | void ShapeUpgrade_WireDivide::Perform () |
266 | { |
267 | |
268 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
269 | |
270 | // if (ShapeUpgrade::Debug()) cout << "ShapeUpgrade_WireDivide::Perform" << endl; |
271 | |
272 | BRep_Builder B; |
273 | ShapeAnalysis_Edge sae; |
274 | |
275 | TopoDS_Wire newWire; |
276 | B.MakeWire (newWire); |
277 | TopLoc_Location Loc; |
278 | Handle(Geom_Surface) Surf; |
279 | if(!myFace.IsNull()) |
280 | Surf = BRep_Tool::Surface(myFace, Loc); |
281 | |
282 | Standard_Boolean isSplit3d = Standard_True; |
283 | switch(myEdgeMode) { |
284 | case 0: if(!myFace.IsNull()) isSplit3d = Standard_False; break; |
285 | case 1: if(myFace.IsNull()) isSplit3d = Standard_False; break; |
286 | default : break; |
287 | } |
288 | myEdgeDivide->SetFace(myFace); |
289 | if(isSplit3d) |
290 | myEdgeDivide->SetSplitCurve3dTool(GetSplitCurve3dTool()); |
291 | myEdgeDivide->SetSplitCurve2dTool(GetSplitCurve2dTool()); |
292 | for (TopoDS_Iterator ItW (myWire,Standard_False); ItW.More(); ItW.Next()) { |
293 | // for each Edge: |
294 | TopoDS_Shape sh = Context()->Apply(ItW.Value(),TopAbs_SHAPE); |
295 | for(TopExp_Explorer exp(sh,TopAbs_EDGE); exp.More(); exp.Next()) { |
296 | TopoDS_Edge E = TopoDS::Edge(exp.Current()); |
297 | // if (ShapeUpgrade::Debug()) cout << ".. Edge " << (void*) &(*E.TShape()) << endl; |
298 | |
299 | // skip degenerated edges (and also INTERNAL/EXTERNAL, to avoid failures) |
300 | if ( E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL ) { |
301 | B.Add ( newWire, E ); |
302 | continue; |
303 | } |
304 | |
305 | if(!myEdgeDivide->Compute(E)) { |
306 | B.Add ( newWire, E ); |
307 | continue; |
308 | } |
309 | // first iteration: getting split knots |
310 | // on 3D curve: preliminary |
311 | |
312 | Handle(ShapeAnalysis_TransferParameters) theTransferParamTool = GetTransferParamTool(); |
313 | theTransferParamTool->SetMaxTolerance(MaxTolerance()); |
314 | theTransferParamTool->Init(E,myFace); |
315 | Standard_Boolean wasSR = theTransferParamTool->IsSameRange(); |
316 | |
317 | // on pcurve(s): all knots |
318 | // assume that if seam-edge, its pcurve1 and pcurve2 has the same split knots !!! |
319 | Handle(TColStd_HSequenceOfReal) theKnots3d = myEdgeDivide->Knots3d(); |
320 | Handle(TColStd_HSequenceOfReal) theKnots2d = myEdgeDivide->Knots2d(); |
321 | |
322 | // second iteration: transfer parameters and build segments |
323 | Handle(TColStd_HSequenceOfReal) SplitValues2d; |
324 | Handle(TColStd_HSequenceOfReal) SplitValues3d; |
325 | if(myEdgeDivide->HasCurve2d() && myEdgeDivide->HasCurve3d() ) { |
326 | SplitValues2d = theTransferParamTool->Perform(theKnots3d,Standard_True); |
327 | SplitValues3d = theTransferParamTool->Perform(theKnots2d,Standard_False); |
328 | CorrectSplitValues(theKnots3d,theKnots2d,SplitValues2d,SplitValues3d); |
329 | } |
330 | Handle(ShapeUpgrade_SplitCurve3d) theSplit3dTool = myEdgeDivide->GetSplitCurve3dTool(); |
331 | Handle(ShapeUpgrade_SplitCurve2d) theSplit2dTool = myEdgeDivide->GetSplitCurve2dTool(); |
332 | |
333 | if ( myEdgeDivide->HasCurve2d() ) { |
334 | if(! theKnots3d.IsNull() ) { |
335 | SplitValues2d->Remove(1); |
336 | SplitValues2d->Remove(SplitValues2d->Length()); |
337 | theSplit2dTool->SetSplitValues (SplitValues2d); |
338 | } |
339 | theSplit2dTool->Build(Standard_True); |
340 | } |
341 | if ( myEdgeDivide->HasCurve3d() ) { |
342 | if( ! theKnots2d.IsNull() ) { |
343 | SplitValues3d->Remove(1); |
344 | SplitValues3d->Remove(SplitValues3d->Length()); |
345 | theSplit3dTool->SetSplitValues (SplitValues3d); |
346 | } |
347 | theSplit3dTool->Build (Standard_True); |
348 | } |
349 | // get 2d and 3d split values which should be the same |
350 | if ( myEdgeDivide->HasCurve2d() ) theKnots2d = theSplit2dTool->SplitValues(); |
351 | if ( myEdgeDivide->HasCurve3d() ) theKnots3d = theSplit3dTool->SplitValues(); |
352 | |
353 | Standard_Boolean isSeam = Standard_False; |
354 | if (! myFace.IsNull() ) |
355 | isSeam = BRep_Tool::IsClosed ( E, myFace ); |
356 | Handle(TColGeom2d_HArray1OfCurve) theSegments2d; |
357 | if(myEdgeDivide->HasCurve2d()) |
358 | theSegments2d = theSplit2dTool->GetCurves(); |
359 | Handle(TColGeom2d_HArray1OfCurve) theSegments2dR; |
360 | if ( isSeam ) { |
361 | Handle(Geom2d_Curve) c2; |
362 | Standard_Real f2, l2; |
363 | //smh#8 |
364 | TopoDS_Shape tmpE = E.Reversed(); |
365 | TopoDS_Edge erev = TopoDS::Edge (tmpE ); |
366 | if ( sae.PCurve ( erev, myFace, c2, f2, l2, Standard_False) ) { |
367 | theSplit2dTool->Init (c2, f2, l2); |
368 | if(!theKnots2d.IsNull()) |
369 | theSplit2dTool->SetSplitValues (theKnots2d); |
370 | theSplit2dTool->Perform (Standard_True); |
371 | Handle(TColStd_HSequenceOfReal) revKnots2d = theSplit2dTool->SplitValues(); |
dede2e21 |
372 | if(revKnots2d->Length()!=theKnots2d->Length()) { |
7fd59977 |
373 | isSeam = Standard_False; |
374 | #ifdef DEB |
375 | cout << "Error: ShapeUpgrade_WireDivide: seam has different splitting values on pcurvesd" << endl; |
376 | #endif |
377 | } |
378 | else |
379 | theSegments2dR = theSplit2dTool->GetCurves(); |
380 | } |
381 | else isSeam = Standard_False; |
382 | } |
383 | |
384 | // Exploring theEdge |
385 | TopoDS_Vertex V1o = TopExp::FirstVertex (E, Standard_False); |
386 | TopoDS_Vertex V2o = TopExp::LastVertex (E, Standard_False); |
387 | Standard_Boolean isForward = ( E.Orientation() == TopAbs_FORWARD ); |
388 | Standard_Real TolEdge = BRep_Tool::Tolerance (E); |
389 | Standard_Boolean isDeg = BRep_Tool::Degenerated ( E ); |
390 | |
391 | // Copy vertices to protect original shape against SameParamseter |
392 | //smh#8 |
393 | TopoDS_Shape emptyCopiedV1 = V1o.EmptyCopied(); |
394 | TopoDS_Vertex V1 = TopoDS::Vertex ( emptyCopiedV1 ); |
395 | Context()->Replace ( V1o, V1 ); |
396 | TopoDS_Vertex V2; |
397 | if ( V1o.IsSame ( V2o ) ) { |
398 | //smh#8 |
399 | TopoDS_Shape tmpV = V1.Oriented(V2o.Orientation() ); |
400 | V2 = TopoDS::Vertex ( tmpV ); |
401 | } |
402 | else { |
403 | //smh#8 |
404 | TopoDS_Shape emptyCopied = V2o.EmptyCopied(); |
405 | V2 = TopoDS::Vertex ( emptyCopied ); |
406 | Context()->Replace ( V2o, V2 ); |
407 | } |
408 | |
409 | //collect NM vertices |
410 | |
411 | Standard_Real af,al; |
412 | Handle(Geom_Curve) c3d; |
413 | Adaptor3d_CurveOnSurface AdCS; |
414 | if(myEdgeDivide->HasCurve3d()) |
415 | sae.Curve3d(E,c3d,af,al,Standard_False); |
416 | else if(myEdgeDivide->HasCurve2d() && !Surf.IsNull()) { |
417 | Handle(Geom2d_Curve) c2d; |
418 | sae.PCurve ( E, myFace, c2d, af, al, Standard_False); |
419 | Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface(Surf); |
420 | Handle(Geom2dAdaptor_HCurve) AC2d = new Geom2dAdaptor_HCurve(c2d,af,al); |
421 | AdCS.Load(AC2d); |
422 | AdCS.Load(AdS); |
423 | } |
424 | TopTools_SequenceOfShape aSeqNMVertices; |
425 | TColStd_SequenceOfReal aSeqParNM; |
426 | TopoDS_Iterator aItv(E,Standard_False); |
427 | ShapeAnalysis_Curve sac; |
428 | for ( ; aItv.More() ; aItv.Next()) { |
429 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
430 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
431 | TopoDS_Vertex aVold = TopoDS::Vertex(aItv.Value()); |
432 | aSeqNMVertices.Append(aVold); |
433 | gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aVold)); |
434 | Standard_Real ppar; |
435 | gp_Pnt pproj; |
436 | if(!c3d.IsNull()) |
437 | sac.Project(c3d,aP,Precision(),pproj,ppar,af,al,Standard_False); |
438 | else |
439 | sac.Project(AdCS,aP,Precision(),pproj,ppar); |
440 | aSeqParNM.Append(ppar); |
441 | } |
442 | } |
443 | |
444 | // creating new edge(s) |
445 | Handle(TColGeom_HArray1OfCurve) theSegments3d; |
446 | if(myEdgeDivide->HasCurve3d()) theSegments3d = theSplit3dTool->GetCurves(); |
447 | |
448 | Standard_Integer nbc = 0; |
449 | if (!theSegments3d.IsNull()) { |
450 | nbc = theSegments3d->Length(); |
451 | if ( !theSegments2d.IsNull() ) { |
452 | Standard_Integer nbc2d = theSegments2d->Length(); |
453 | if (nbc!=nbc2d) { |
454 | #ifdef DEB |
455 | cout<<"Error: Number of intervals are not equal for 2d 3d. Ignored."<<endl; |
456 | #endif |
457 | nbc = Min( nbc,nbc2d); |
458 | } |
459 | } |
460 | } |
461 | else |
462 | if(!theSegments2d.IsNull())// if theSegments have different length ??? |
463 | nbc = theSegments2d->Length(); |
464 | |
465 | if ( nbc <= 1 && ! theSplit3dTool->Status ( ShapeExtend_DONE ) && |
466 | ! theSplit2dTool->Status ( ShapeExtend_DONE ) ) { |
467 | B.Add ( newWire, E ); |
468 | continue; |
469 | } |
470 | |
471 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
472 | |
473 | TopoDS_Wire resWire; |
474 | B.MakeWire (resWire); |
475 | // TopoDS_Vertex firstVertex, lastVertex; |
476 | Standard_Integer numE =0; |
477 | gp_Pnt pntV1 = BRep_Tool::Pnt(V1); |
478 | //gp_Pnt pntV2 = BRep_Tool::Pnt(V2); // pntV2 not used - see below (skl) |
479 | Standard_Real V1Tol = LimitTolerance( BRep_Tool::Tolerance(V1) ); |
480 | //Standard_Real V2Tol = LimitTolerance( BRep_Tool::Tolerance(V2) ); // V2Tol not used - see below (skl) |
481 | |
482 | Handle(ShapeUpgrade_FixSmallCurves) FixSmallCurveTool = GetFixSmallCurveTool(); //gka Precision |
483 | FixSmallCurveTool->SetMinTolerance(MinTolerance()); |
484 | FixSmallCurveTool->Init(E, myFace); |
485 | FixSmallCurveTool->SetSplitCurve3dTool(theSplit3dTool); |
486 | FixSmallCurveTool->SetSplitCurve2dTool(theSplit2dTool); |
487 | FixSmallCurveTool->SetPrecision(MinTolerance()); |
488 | Standard_Integer Savnum =0; |
489 | Standard_Real SavParf; |
490 | Standard_Integer Small = 0; |
491 | for ( Standard_Integer icurv = 1; icurv <= nbc; icurv++ ) { |
492 | |
493 | Handle(Geom_Curve) theNewCurve3d; |
494 | if(!theSegments3d.IsNull()) theNewCurve3d = theSegments3d->Value(icurv); |
495 | |
496 | Handle(Geom2d_Curve) theNewPCurve1; |
497 | if(!theSegments2d.IsNull()) theNewPCurve1 = theSegments2d->Value(icurv); |
498 | Handle(Geom2d_Curve) revPCurve; |
499 | if(isSeam) |
500 | revPCurve = theSegments2dR->Value(icurv); |
501 | // construction of the intermediate Vertex |
502 | TopoDS_Vertex V; |
503 | if ( icurv <= nbc && nbc != 1 && ! isDeg ) { |
504 | Standard_Real par,parf /*,SavParl*/; |
505 | //Standard_Real SaveParf; // SaveParf not used - see below (skl) |
506 | gp_Pnt P,P1,PM; |
507 | // if edge has 3d curve, take point from it |
508 | if ( ! theNewCurve3d.IsNull() ) { |
509 | if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { |
510 | par = theNewCurve3d->LastParameter(); |
511 | parf = theNewCurve3d->FirstParameter(); |
512 | } |
513 | else { |
514 | par = theKnots3d->Value (icurv + 1); |
515 | parf = theKnots3d->Value (icurv); |
516 | } |
517 | P = theNewCurve3d->Value (par); |
518 | P1 = theNewCurve3d->Value (parf); |
519 | PM = theNewCurve3d->Value ((parf+par)/2); |
520 | } |
521 | // else use pcurve and surface (suppose that both exist) |
522 | else { |
523 | if ( Surf.IsNull() ) Surf = BRep_Tool::Surface ( myFace, Loc ); |
524 | if ( theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) ) { |
525 | par = theNewPCurve1->LastParameter(); |
526 | parf = theNewPCurve1->FirstParameter(); |
527 | } |
528 | else { |
529 | par = theKnots2d->Value (icurv + 1); |
530 | parf = theKnots2d->Value (icurv); |
531 | } |
532 | gp_Pnt2d p2d = theNewPCurve1->Value (par); |
533 | gp_Pnt2d p2df = theNewPCurve1->Value (parf); |
534 | gp_Pnt2d p2dM = theNewPCurve1->Value ((parf+par)/2); |
535 | P = Surf->Value ( p2d.X(), p2d.Y() ); |
536 | P1 = Surf->Value ( p2df.X(), p2df.Y() ); |
537 | PM = Surf->Value ( p2dM.X(), p2dM.Y() ); |
538 | P.Transform ( Loc.Transformation() ); |
539 | P1.Transform ( Loc.Transformation() ); |
540 | PM.Transform ( Loc.Transformation() ); |
541 | } |
542 | if(P.Distance(pntV1) < MinTolerance() && P.Distance(PM) < MinTolerance() && !myFace.IsNull()) { |
543 | if(!Small) { |
544 | SavParf = parf; |
545 | Savnum = icurv; |
546 | } |
547 | //SavParl = par; |
548 | Small++; |
549 | if(icurv == nbc) { |
550 | TopoDS_Vertex VVV = V1; |
551 | VVV.Orientation ( V2.Orientation() ); |
552 | Context()->Replace(V2,VVV); |
553 | } |
554 | continue; |
555 | } |
556 | if(Small) { |
557 | if(P.Distance(P1) > MinTolerance() || P.Distance(PM) > MinTolerance()) { |
558 | //FixSmallCurveTool->Perform(prevEdge,theNewCurve3d,theNewPCurve1,revPCurve,SavParf,SavParl); |
559 | gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() ); |
560 | B.UpdateVertex(V1,pmid,0); |
561 | } |
562 | else { |
563 | Handle(Geom_Curve) atmpCurve; |
564 | Handle(Geom2d_Curve) atmpCurve2d1,atmprepcurve; |
565 | if(FixSmallCurveTool->Approx( atmpCurve,atmpCurve2d1,atmprepcurve,SavParf,par)) { //BRepTools |
566 | theNewCurve3d = atmpCurve; |
567 | theNewPCurve1 = atmpCurve2d1; |
568 | revPCurve = atmprepcurve; |
569 | } |
570 | else { |
571 | gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() ); |
572 | B.UpdateVertex(V1,pmid,0); |
573 | } |
574 | } |
575 | Small =0; |
576 | } |
577 | //pdn |
578 | /* if(P.Distance (pntV1) < V1Tol) |
579 | V = V1; |
580 | else if (P.Distance (pntV2) < V2Tol) { |
581 | V = V2; |
582 | V1Tol = V2Tol; |
583 | pntV1 = pntV2; |
584 | } |
585 | else {*/ |
586 | if(icurv != nbc) { |
587 | B.MakeVertex (V, P, TolEdge); //tolerance of the edge |
588 | pntV1 = P; |
589 | V1Tol = LimitTolerance( TolEdge ); |
590 | } |
591 | else V = V2; |
592 | // else V2; |
593 | // } |
594 | // if (ShapeUpgrade::Debug()) cout <<"... New intermediate Vertex (" |
595 | // <<P.X()<<","<<P.Y()<<","<<P.Z()<<") :"<<(void*) &(*V.TShape()) |
596 | // <<" with Tolerance "<<TolEdge <<endl; |
597 | } |
598 | //else V = V2; |
599 | |
600 | TopoDS_Edge newEdge; |
601 | ShapeBuild_Edge sbe; |
602 | if ( isForward ) { |
603 | V1.Orientation ( TopAbs_FORWARD ); |
604 | V.Orientation ( TopAbs_REVERSED ); |
605 | newEdge = sbe.CopyReplaceVertices ( E, V1, V ); |
606 | } |
607 | else { |
608 | V1.Orientation ( TopAbs_REVERSED ); |
609 | V.Orientation ( TopAbs_FORWARD ); |
610 | newEdge = sbe.CopyReplaceVertices ( E, V, V1 ); |
611 | } |
612 | sbe.CopyPCurves ( newEdge, E ); |
613 | if(!theNewCurve3d.IsNull()) |
614 | B.UpdateEdge ( newEdge, theNewCurve3d, 0. ); |
615 | else if ( isDeg ) |
616 | B.Degenerated( newEdge, Standard_True); |
617 | //if(isSeam) { |
618 | // Handle(Geom2d_Curve) revPCurve = theSegments2dR->Value(icurv); |
619 | //if(newEdge.Orientation()==TopAbs_FORWARD) |
620 | //B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. ); |
621 | //else |
622 | //B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. ); |
623 | //} |
624 | //else if ( ! myFace.IsNull() ) |
625 | //B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. ); |
626 | |
627 | Standard_Real f3d = 0., l3d =0.; |
628 | if(!Savnum) Savnum = icurv; |
629 | Standard_Boolean srNew; |
630 | if(!theNewCurve3d.IsNull()) { |
631 | if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { |
632 | f3d = theNewCurve3d->FirstParameter(); |
633 | l3d = theNewCurve3d->LastParameter(); |
634 | srNew = ((f3d == theKnots3d->Value (Savnum)) && (l3d == theKnots3d->Value (icurv + 1))); |
635 | } |
636 | else { |
637 | f3d = theKnots3d->Value (Savnum); |
638 | l3d = theKnots3d->Value (icurv + 1); |
639 | srNew = Standard_True; |
640 | } |
641 | } |
642 | else |
643 | srNew = Standard_True; |
644 | |
645 | Standard_Real f2d=0, l2d=0; |
646 | if(!theNewPCurve1.IsNull()){ |
647 | if(theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) { |
648 | f2d = theNewPCurve1->FirstParameter(); |
649 | l2d = theNewPCurve1->LastParameter(); |
650 | srNew &= ((f2d == theKnots2d->Value (Savnum)) && (l2d == theKnots2d->Value (icurv + 1))); |
651 | } |
652 | else { |
653 | f2d = theKnots2d->Value (Savnum); |
654 | l2d = theKnots2d->Value (icurv + 1); |
655 | } |
656 | } |
657 | //if(!Savnum) Savnum = icurv; |
658 | if(!theNewCurve3d.IsNull()) |
659 | theTransferParamTool->TransferRange(newEdge,theKnots3d->Value (Savnum),theKnots3d->Value (icurv + 1),Standard_False); |
660 | else |
661 | theTransferParamTool->TransferRange(newEdge,theKnots2d->Value (Savnum),theKnots2d->Value (icurv + 1),Standard_True); |
662 | /* |
663 | Standard_Real alpha = (theKnots3d->Value (icurv) - f)/(l - f); |
664 | Standard_Real beta = (theKnots3d->Value (icurv + 1) - f)/(l - f); |
665 | sbe.CopyRanges(newEdge,E, alpha, beta);*/ |
666 | Savnum =0; |
667 | Handle(Geom2d_Curve) c2dTmp; |
668 | Standard_Real setF, setL; |
669 | if( ! myFace.IsNull() && sae.PCurve (newEdge, myFace, c2dTmp, setF, setL, Standard_False)) |
670 | srNew &= ( (setF==f2d) && (setL==l2d) ); |
671 | |
672 | if(isSeam) { |
673 | // Handle(Geom2d_Curve revPCurve = theSegments2dR->Value(icurv); |
674 | if(newEdge.Orientation()==TopAbs_FORWARD) |
675 | B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. ); |
676 | else |
677 | B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. ); |
678 | } |
679 | else if ( ! myFace.IsNull() ) { |
680 | B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. ); |
681 | } |
682 | |
683 | if(!theNewCurve3d.IsNull()) |
684 | sbe.SetRange3d(newEdge,f3d,l3d); |
685 | if(!theNewPCurve1.IsNull()) |
686 | B.Range ( newEdge, myFace, f2d, l2d); |
687 | if((!wasSR || !srNew)&&!BRep_Tool::Degenerated(newEdge) ) |
688 | B.SameRange(newEdge, Standard_False); |
689 | |
690 | //addition NM vertices to new edges |
691 | Standard_Real afpar = (myEdgeDivide->HasCurve3d() ? f3d : f2d); |
692 | |
693 | Standard_Real alpar = (myEdgeDivide->HasCurve3d() ? l3d: l2d); |
694 | Standard_Integer n =1; |
695 | for( ; n <= aSeqParNM.Length(); n++) { |
696 | Standard_Real apar = aSeqParNM.Value(n); |
697 | TopoDS_Vertex aVold = TopoDS::Vertex(aSeqNMVertices.Value(n)); |
698 | TopoDS_Vertex aNMVer =ShapeAnalysis_TransferParametersProj::CopyNMVertex(aVold,newEdge,E); |
699 | Context()->Replace(aVold,aNMVer); |
700 | if(fabs(apar - afpar) <= Precision::PConfusion()) |
701 | Context()->Replace(aNMVer,V1); |
702 | else if(fabs(apar - alpar) <= Precision::PConfusion()) |
703 | Context()->Replace(aNMVer,V); |
704 | else if( apar > afpar && apar <alpar) |
705 | B.Add (newEdge,aNMVer); |
706 | else continue; |
707 | aSeqNMVertices.Remove(n); |
708 | aSeqParNM.Remove(n); |
709 | n--; |
710 | } |
711 | |
712 | |
713 | // if (ShapeUpgrade::Debug()) cout <<"... New Edge " |
714 | // <<(void*) &(*newEdge.TShape())<<" on vertices " |
715 | // <<(void*) &(*V1.TShape())<<", " <<(void*) &(*V.TShape()) |
716 | // <<" with Tolerance "<<TolEdge <<endl; |
717 | B.Add ( resWire, newEdge ); |
718 | B.Add ( newWire, newEdge ); |
719 | numE++; |
720 | V1 = V; |
721 | } |
722 | if(numE) |
723 | Context()->Replace(E,resWire); |
724 | else |
725 | Context()->Remove(E); |
726 | } |
727 | } |
728 | if ( Status ( ShapeExtend_DONE ) ) { |
729 | //smh#8 |
730 | TopoDS_Shape tmpW = Context()->Apply ( newWire ).Oriented(myWire.Orientation()); |
731 | myWire = TopoDS::Wire (tmpW ); |
732 | } |
733 | } |
734 | |
735 | //======================================================================= |
736 | //function : Face |
737 | //purpose : |
738 | //======================================================================= |
739 | |
740 | const TopoDS_Wire& ShapeUpgrade_WireDivide::Wire() const |
741 | { |
742 | return myWire; |
743 | } |
744 | |
745 | //======================================================================= |
746 | //function : Status |
747 | //purpose : |
748 | //======================================================================= |
749 | |
750 | Standard_Boolean ShapeUpgrade_WireDivide::Status (const ShapeExtend_Status status) const |
751 | { |
752 | return ShapeExtend::DecodeStatus ( myStatus, status ); |
753 | } |
754 | |
755 | //======================================================================= |
756 | //function : SetSplitCurve3dTool |
757 | //purpose : |
758 | //======================================================================= |
759 | |
760 | void ShapeUpgrade_WireDivide::SetSplitCurve3dTool(const Handle(ShapeUpgrade_SplitCurve3d)& splitCurve3dTool) |
761 | { |
762 | mySplitCurve3dTool = splitCurve3dTool; |
763 | } |
764 | |
765 | //======================================================================= |
766 | //function : SetSplitCurve2dTool |
767 | //purpose : |
768 | //======================================================================= |
769 | |
770 | void ShapeUpgrade_WireDivide::SetSplitCurve2dTool(const Handle(ShapeUpgrade_SplitCurve2d)& splitCurve2dTool) |
771 | { |
772 | mySplitCurve2dTool = splitCurve2dTool; |
773 | } |
774 | |
775 | //======================================================================= |
776 | //function : GetSplitCurve3dTool |
777 | //purpose : |
778 | //======================================================================= |
779 | |
780 | Handle(ShapeUpgrade_SplitCurve3d) ShapeUpgrade_WireDivide::GetSplitCurve3dTool() const |
781 | { |
782 | return mySplitCurve3dTool; |
783 | } |
784 | |
785 | //======================================================================= |
786 | //function : GetSplitCurve2dTool |
787 | //purpose : |
788 | //======================================================================= |
789 | |
790 | Handle(ShapeUpgrade_SplitCurve2d) ShapeUpgrade_WireDivide::GetSplitCurve2dTool() const |
791 | { |
792 | return mySplitCurve2dTool; |
793 | } |
794 | |
795 | //======================================================================= |
796 | //function : SetEdgeDivideTool |
797 | //purpose : |
798 | //======================================================================= |
799 | |
800 | void ShapeUpgrade_WireDivide::SetEdgeDivideTool(const Handle (ShapeUpgrade_EdgeDivide)& edgeDivideTool) |
801 | { |
802 | myEdgeDivide = edgeDivideTool; |
803 | } |
804 | |
805 | //======================================================================= |
806 | //function : GetEdgeDivideTool |
807 | //purpose : |
808 | //======================================================================= |
809 | |
810 | Handle (ShapeUpgrade_EdgeDivide) ShapeUpgrade_WireDivide::GetEdgeDivideTool() const |
811 | { |
812 | return myEdgeDivide; |
813 | } |
814 | |
815 | //======================================================================= |
816 | //function : SetTransferParamTool |
817 | //purpose : |
818 | //======================================================================= |
819 | |
820 | void ShapeUpgrade_WireDivide::SetTransferParamTool(const Handle(ShapeAnalysis_TransferParameters)& TransferParam) |
821 | { |
822 | myTransferParamTool = TransferParam; |
823 | } |
824 | |
825 | //======================================================================= |
826 | //function : GetTransferParamTool |
827 | //purpose : |
828 | //======================================================================= |
829 | |
830 | Handle(ShapeAnalysis_TransferParameters) ShapeUpgrade_WireDivide::GetTransferParamTool() |
831 | { |
832 | return myTransferParamTool; |
833 | } |
834 | |
835 | //======================================================================= |
836 | //function : SetEdgeMode |
837 | //purpose : |
838 | //======================================================================= |
839 | |
840 | void ShapeUpgrade_WireDivide::SetEdgeMode(const Standard_Integer EdgeMode) |
841 | { |
842 | myEdgeMode = EdgeMode; |
843 | } |
844 | |
845 | //======================================================================= |
846 | //function : SetFixSmallCurveTool |
847 | //purpose : |
848 | //======================================================================= |
849 | |
850 | void ShapeUpgrade_WireDivide::SetFixSmallCurveTool(const Handle(ShapeUpgrade_FixSmallCurves)& FixSmallCurvesTool) |
851 | { |
852 | myFixSmallCurveTool = FixSmallCurvesTool; |
853 | } |
854 | |
855 | //======================================================================= |
856 | //function : GetFixSmallCurveTool |
857 | //purpose : |
858 | //======================================================================= |
859 | |
860 | Handle(ShapeUpgrade_FixSmallCurves) ShapeUpgrade_WireDivide::GetFixSmallCurveTool() const |
861 | { |
862 | return myFixSmallCurveTool; |
863 | } |