b311480e |
1 | // Created on: 1993-02-05 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1993-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | #define Tolpetit 1.e-10 // pour dist au carre |
23 | #include <ElSLib.hxx> |
24 | |
25 | |
26 | #include <TColStd_SequenceOfInteger.hxx> |
27 | |
28 | static Standard_Boolean FindLine(Contap_TheLine& Line, |
29 | const TheSurface& Surf, |
30 | const gp_Pnt2d& Pt2d, |
31 | gp_Pnt& Ptref, |
32 | Standard_Real& Paramin, |
33 | gp_Vec& Tgmin, |
34 | gp_Vec& Norm) |
35 | { |
36 | // Standard_Integer i; |
37 | gp_Pnt pt,ptmin; |
38 | gp_Vec tg; |
39 | Standard_Real para,dist; |
40 | Standard_Real dismin = RealLast(); |
41 | |
42 | Contap_TheSurfProps::Normale(Surf,Pt2d.X(),Pt2d.Y(),Ptref,Norm); |
43 | |
44 | if (Line.TypeContour() == Contap_Lin) { |
45 | gp_Lin lin(Line.Line()); |
46 | para = ElCLib::Parameter(lin,Ptref); |
47 | ElCLib::D1(para,lin,pt,tg); |
48 | dist = pt.Distance(Ptref) + Abs(Norm.Dot(lin.Direction())); |
49 | } |
50 | else { // Contap__Circle |
51 | gp_Circ cir(Line.Circle()); |
52 | para = ElCLib::Parameter(cir,Ptref); |
53 | ElCLib::D1(para,cir,pt,tg); |
54 | dist = pt.Distance(Ptref)+Abs(Norm.Dot(tg/cir.Radius())); |
55 | } |
56 | if (dist < dismin) { |
57 | dismin = dist; |
58 | Paramin = para; |
59 | ptmin = pt; |
60 | Tgmin = tg; |
61 | } |
62 | if (ptmin.SquareDistance(Ptref) <= Tolpetit) { |
63 | return Standard_True; |
64 | } |
65 | else { |
66 | return Standard_False; |
67 | } |
68 | } |
69 | |
70 | |
71 | static void PutPointsOnLine (const Contap_TheSearch& solrst, |
72 | const TheSurface& Surf, |
73 | Contap_TheSequenceOfLine& slin) |
74 | |
75 | { |
76 | Standard_Integer i,l;//,index; |
77 | Standard_Integer NbPoints = solrst.NbPoints(); |
78 | |
79 | Standard_Real theparam; |
80 | |
81 | IntSurf_Transition TLine,TArc; |
82 | Standard_Boolean goon; |
83 | |
84 | gp_Pnt2d pt2d; |
85 | gp_Vec2d d2d; |
86 | |
87 | gp_Pnt ptonsurf; |
88 | gp_Vec vectg,normale,tgtrst; |
89 | Standard_Real paramlin; |
90 | |
91 | |
92 | Standard_Integer nbLin = slin.Length(); |
93 | for(l=1;l<=nbLin;l++) { |
94 | Contap_TheLine& Line=slin.ChangeValue(l); |
95 | for (i=1; i<= NbPoints; i++) { |
96 | |
97 | const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i); |
98 | const TheArc& thearc = PStart.Arc(); |
99 | theparam = PStart.Parameter(); |
100 | |
101 | TheArcTool::D1(thearc,theparam,pt2d,d2d); |
102 | goon = FindLine(Line,Surf,pt2d,ptonsurf,paramlin,vectg,normale); |
103 | |
104 | Contap_ThePoint PPoint; |
105 | |
106 | if (goon) { |
107 | gp_Vec d1u,d1v; |
108 | gp_Pnt bidpt; |
109 | TheSurfaceTool::D1(Surf,pt2d.X(),pt2d.Y(),bidpt,d1u,d1v); |
110 | PPoint.SetValue(ptonsurf,pt2d.X(),pt2d.Y()); |
111 | if (normale.Magnitude() < RealEpsilon()) { |
112 | TLine.SetValue(); |
113 | TArc.SetValue(); |
114 | } |
115 | else { |
116 | // Petit test qui devrait permettre de bien traiter les pointes |
117 | // des cones, et les sommets d`une sphere. Il faudrait peut-etre |
118 | // rajouter une methode dans SurfProps |
119 | |
120 | if (Abs(d2d.Y()) <= Precision::Confusion()) { |
121 | tgtrst = d1v.Crossed(normale); |
122 | if(d2d.X() < 0.0) |
123 | tgtrst.Reverse(); |
124 | } |
125 | else { |
126 | tgtrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); |
127 | } |
128 | IntSurf::MakeTransition(vectg,tgtrst,normale,TLine,TArc); |
129 | } |
130 | |
131 | PPoint.SetArc(thearc,theparam, TLine, TArc); |
132 | PPoint.SetParameter(paramlin); |
133 | if (!PStart.IsNew()) { |
134 | PPoint.SetVertex(PStart.Vertex()); |
135 | } |
136 | Line.Add(PPoint); |
137 | } |
138 | } |
139 | } |
140 | } |
141 | |
142 | |
143 | //---------------------------------------------------------------------------------- |
144 | //-- Orientation des contours Apparents quand ceux-ci sont des lignes ou des cercles |
145 | //-- On prend un point de la ligne ou du cercle ---> P |
146 | //-- On projete ce point sur la surface P ---> u,v |
147 | //-- et on evalue la transition au point u,v |
148 | //---------------------------------------------------------------------------------- |
149 | |
150 | IntSurf_TypeTrans ComputeTransitionOngpLine |
151 | (Contap_TheSurfFunction& SFunc, |
152 | const gp_Lin& L) |
153 | { |
154 | const TheSurface& Surf=SFunc.Surface(); |
155 | GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(Surf); |
156 | gp_Pnt P; |
157 | gp_Vec T; |
158 | ElCLib::D1(0.0,L,P,T); |
159 | Standard_Real u,v; |
160 | switch (typS) { |
161 | case GeomAbs_Cylinder: { |
162 | ElSLib::Parameters(TheSurfaceTool::Cylinder(Surf),P,u,v); |
163 | break; |
164 | } |
165 | case GeomAbs_Cone: { |
166 | ElSLib::Parameters(TheSurfaceTool::Cone(Surf),P,u,v); |
167 | break; |
168 | } |
169 | case GeomAbs_Sphere: { |
170 | ElSLib::Parameters(TheSurfaceTool::Sphere(Surf),P,u,v); |
171 | break; |
172 | } |
7fd59977 |
173 | default: |
174 | break; |
7fd59977 |
175 | } |
176 | return(ComputeTransitionOnLine(SFunc,u,v,T)); |
177 | } |
178 | |
179 | |
180 | IntSurf_TypeTrans ComputeTransitionOngpCircle |
181 | (Contap_TheSurfFunction& SFunc, |
182 | const gp_Circ& C) |
183 | { |
184 | const TheSurface& Surf=SFunc.Surface(); |
185 | GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(Surf); |
186 | gp_Pnt P; |
187 | gp_Vec T; |
188 | ElCLib::D1(0.0,C,P,T); |
189 | Standard_Real u,v; |
190 | switch (typS) { |
191 | case GeomAbs_Cylinder: { |
192 | ElSLib::Parameters(TheSurfaceTool::Cylinder(Surf),P,u,v); |
193 | break; |
194 | } |
195 | case GeomAbs_Cone: { |
196 | ElSLib::Parameters(TheSurfaceTool::Cone(Surf),P,u,v); |
197 | break; |
198 | } |
199 | case GeomAbs_Sphere: { |
200 | ElSLib::Parameters(TheSurfaceTool::Sphere(Surf),P,u,v); |
201 | break; |
202 | } |
7fd59977 |
203 | default: |
204 | break; |
7fd59977 |
205 | } |
206 | return(ComputeTransitionOnLine(SFunc,u,v,T)); |
7fd59977 |
207 | } |
208 | |
209 | |
210 | void Contap_ContourGen::PerformAna(const Handle(TheTopolTool)& Domain) |
211 | { |
212 | |
213 | done = Standard_False; |
214 | slin.Clear(); |
215 | |
216 | Standard_Real TolArc = 1.e-5; |
217 | |
218 | Standard_Integer nbCont, nbPointRst, i; |
219 | //gp_Circ cirsol; |
220 | //gp_Lin linsol; |
221 | Contap_ContAna contana; |
222 | Contap_TheLine theline; |
223 | const TheSurface& Surf = mySFunc.Surface(); |
224 | Contap_TFunction TypeFunc(mySFunc.FunctionType()); |
225 | Standard_Boolean PerformSolRst = Standard_True; |
226 | |
227 | GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(Surf); |
228 | |
229 | switch (typS) { |
230 | case GeomAbs_Plane: |
231 | { |
232 | gp_Pln pl(TheSurfaceTool::Plane(Surf)); |
233 | switch (TypeFunc) { |
234 | case Contap_ContourStd: |
235 | { |
236 | gp_Dir Dirpln(pl.Axis().Direction()); |
237 | if (Abs(mySFunc.Direction().Dot(Dirpln)) > Precision::Angular()) { |
238 | // Aucun point du plan n`est solution, en particulier aucun point |
239 | // sur restriction. |
240 | PerformSolRst = Standard_False; |
241 | } |
242 | } |
243 | break; |
244 | case Contap_ContourPrs: |
245 | { |
246 | gp_Pnt Eye(mySFunc.Eye()); |
247 | if (pl.Distance(Eye) > Precision::Confusion()) { |
248 | // Aucun point du plan n`est solution, en particulier aucun point |
249 | // sur restriction. |
250 | PerformSolRst = Standard_False; |
251 | } |
252 | } |
253 | break; |
254 | case Contap_DraftStd: |
255 | { |
256 | gp_Dir Dirpln(pl.Axis().Direction()); |
257 | Standard_Real Sina = Sin(mySFunc.Angle()); |
258 | if (Abs(mySFunc.Direction().Dot(Dirpln)+ Sina) > //voir SurfFunction |
259 | Precision::Angular()) { |
260 | |
261 | PerformSolRst = Standard_False; |
262 | } |
263 | } |
264 | break; |
265 | case Contap_DraftPrs: |
266 | default: |
267 | { |
268 | } |
269 | } |
270 | } |
271 | break; |
272 | |
273 | case GeomAbs_Sphere: |
274 | { |
275 | switch (TypeFunc) { |
276 | case Contap_ContourStd: |
277 | { |
278 | contana.Perform(TheSurfaceTool::Sphere(Surf),mySFunc.Direction()); |
279 | } |
280 | break; |
281 | case Contap_ContourPrs: |
282 | { |
283 | contana.Perform(TheSurfaceTool::Sphere(Surf),mySFunc.Eye()); |
284 | } |
285 | break; |
286 | case Contap_DraftStd: |
287 | { |
288 | contana.Perform(TheSurfaceTool::Sphere(Surf), |
289 | mySFunc.Direction(),mySFunc.Angle()); |
290 | } |
291 | break; |
292 | case Contap_DraftPrs: |
293 | default: |
294 | { |
295 | } |
296 | } |
297 | } |
298 | break; |
299 | |
300 | case GeomAbs_Cylinder: |
301 | { |
302 | switch (TypeFunc) { |
303 | case Contap_ContourStd: |
304 | { |
305 | contana.Perform(TheSurfaceTool::Cylinder(Surf),mySFunc.Direction()); |
306 | } |
307 | break; |
308 | case Contap_ContourPrs: |
309 | { |
310 | contana.Perform(TheSurfaceTool::Cylinder(Surf),mySFunc.Eye()); |
311 | } |
312 | break; |
313 | case Contap_DraftStd: |
314 | { |
315 | contana.Perform(TheSurfaceTool::Cylinder(Surf), |
316 | mySFunc.Direction(),mySFunc.Angle()); |
317 | } |
318 | break; |
319 | case Contap_DraftPrs: |
320 | default: |
321 | { |
322 | } |
323 | } |
324 | } |
325 | break; |
326 | |
327 | case GeomAbs_Cone: |
328 | { |
329 | switch (TypeFunc) { |
330 | case Contap_ContourStd: |
331 | { |
332 | contana.Perform(TheSurfaceTool::Cone(Surf),mySFunc.Direction()); |
333 | } |
334 | break; |
335 | case Contap_ContourPrs: |
336 | { |
337 | contana.Perform(TheSurfaceTool::Cone(Surf),mySFunc.Eye()); |
338 | } |
339 | break; |
340 | case Contap_DraftStd: |
341 | { |
342 | contana.Perform(TheSurfaceTool::Cone(Surf), |
343 | mySFunc.Direction(),mySFunc.Angle()); |
344 | } |
345 | break; |
346 | case Contap_DraftPrs: |
347 | default: |
348 | { |
349 | } |
350 | } |
7fd59977 |
351 | default: |
352 | break; |
7fd59977 |
353 | } |
354 | break; |
355 | } |
356 | |
357 | if (typS != GeomAbs_Plane) { |
358 | |
359 | if (!contana.IsDone()) { |
360 | return; |
361 | } |
362 | |
363 | nbCont = contana.NbContours(); |
364 | |
365 | if (contana.NbContours() == 0) { |
366 | done = Standard_True; |
367 | return; |
368 | } |
369 | |
370 | GeomAbs_CurveType typL = contana.TypeContour(); |
371 | if (typL == GeomAbs_Circle) { |
372 | theline.SetValue(contana.Circle()); |
373 | IntSurf_TypeTrans TransCircle; |
374 | TransCircle = ComputeTransitionOngpCircle(mySFunc,contana.Circle()); |
375 | theline.SetTransitionOnS(TransCircle); |
376 | slin.Append(theline); |
377 | } |
378 | else if (typL == GeomAbs_Line) { |
379 | for (i=1; i<=nbCont; i++) { |
380 | theline.SetValue(contana.Line(i)); |
381 | IntSurf_TypeTrans TransLine; |
382 | TransLine = ComputeTransitionOngpLine(mySFunc,contana.Line(i)); |
383 | theline.SetTransitionOnS(TransLine); |
384 | slin.Append(theline); |
385 | theline.Clear(); |
386 | } |
387 | |
388 | /* |
389 | if (typS == GeomAbs_Cone) { |
390 | Standard_Real u,v; |
391 | gp_Cone thecone(TheSurfaceTool::Cone(Surf)); |
392 | ElSLib::Parameters(thecone,thecone.Apex(),u,v); |
393 | Contap_ThePoint vtxapex(thecone.Apex(),u,v); |
394 | vtxapex.SetInternal(); |
395 | vtxapex.SetMultiple(); |
396 | for (i=1; i<=nbCont i++) { |
397 | slin.ChangeValue(i).Add(vtxapex); |
398 | } |
399 | } |
400 | */ |
401 | } |
402 | } |
403 | |
404 | if(PerformSolRst) { |
405 | |
406 | solrst.Perform(myAFunc,Domain,TolArc,TolArc); |
407 | if (!solrst.IsDone()) { |
408 | return; |
409 | } |
410 | nbPointRst = solrst.NbPoints(); |
411 | |
412 | if (nbPointRst != 0) { |
413 | PutPointsOnLine(solrst,Surf,slin); |
414 | } |
415 | |
416 | if (solrst.NbSegments() !=0) { |
417 | ProcessSegments(solrst,slin,TolArc,mySFunc,Domain); |
418 | } |
419 | |
420 | |
421 | //-- lbr |
422 | //Standard_Boolean oneremov; |
423 | Standard_Integer nblinto = slin.Length(); |
424 | TColStd_SequenceOfInteger SeqToDestroy; |
425 | |
426 | //-- cout<<" Construct Contour_3 nblin = "<<nblinto<<endl; |
427 | for(i=1; i<= nblinto ; i++) { |
428 | //-- cout<<" nbvtx : "<<slin.Value(i).NbVertex()<<endl; |
429 | //--if(slin.Value(i).NbVertex() > 1) { |
430 | if(slin.Value(i).TypeContour() != Contap_Restriction) { |
431 | LineConstructor(slin,Domain,slin.ChangeValue(i),Surf); |
432 | SeqToDestroy.Append(i); |
433 | } |
434 | //-- } |
435 | } |
436 | for(i=SeqToDestroy.Length(); i>=1; i--) { |
437 | slin.Remove(SeqToDestroy.Value(i)); |
438 | } |
439 | } |
440 | |
441 | done = Standard_True; |
442 | } |
443 | |
444 | |
445 | |
446 | |
447 | |