0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / TPrsStd / TPrsStd_ConstraintTools.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 // Language:    C++
15 // Version:     Euclid Designer 2.0
16 // Purpose:     Update AIS object from a TDataXtd_Constraint.
17 // Modified     Mon 30 10:15:43 1998 by SZY
18
19 #include <TPrsStd_ConstraintTools.hxx>
20
21 #include <AIS_InteractiveContext.hxx>
22 #include <AIS_InteractiveObject.hxx>
23 #include <PrsDim_AngleDimension.hxx>
24 #include <PrsDim_ConcentricRelation.hxx>
25 #include <PrsDim_DiameterDimension.hxx>
26 #include <PrsDim_EqualDistanceRelation.hxx>
27 #include <PrsDim_EqualRadiusRelation.hxx>
28 #include <PrsDim_FixRelation.hxx>
29 #include <PrsDim_IdenticRelation.hxx>
30 #include <PrsDim_LengthDimension.hxx>
31 #include <PrsDim_MaxRadiusDimension.hxx>
32 #include <PrsDim_MidPointRelation.hxx>
33 #include <PrsDim_MinRadiusDimension.hxx>
34 #include <PrsDim_OffsetDimension.hxx>
35 #include <PrsDim_ParallelRelation.hxx>
36 #include <PrsDim_PerpendicularRelation.hxx>
37 #include <PrsDim_RadiusDimension.hxx>
38 #include <PrsDim_Relation.hxx>
39 #include <PrsDim_SymmetricRelation.hxx>
40 #include <PrsDim_TangentRelation.hxx>
41 #include <BRep_Builder.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRepAdaptor_Curve.hxx>
44 #include <BRepAdaptor_Surface.hxx>
45 #include <BRepBuilderAPI_MakeFace.hxx>
46 #include <GC_MakePlane.hxx>
47 #include <Geom_CartesianPoint.hxx>
48 #include <Geom_Circle.hxx>
49 #include <Geom_Geometry.hxx>
50 #include <Geom_Line.hxx>
51 #include <Geom_Plane.hxx>
52 #include <GeomAbs_SurfaceType.hxx>
53 #include <gp_Ax1.hxx>
54 #include <gp_Cone.hxx>
55 #include <gp_Cylinder.hxx>
56 #include <gp_Dir.hxx>
57 #include <gp_Lin.hxx>
58 #include <gp_Pln.hxx>
59 #include <gp_Pnt.hxx>
60 #include <gp_Torus.hxx>
61 #include <IntAna_QuadQuadGeo.hxx>
62 #include <Precision.hxx>
63 #include <Prs3d_Drawer.hxx>
64 #include <Standard_ErrorHandler.hxx>
65 #include <Standard_ProgramError.hxx>
66 #include <TCollection_ExtendedString.hxx>
67 #include <TDataStd_Name.hxx>
68 #include <TDataStd_Real.hxx>
69 #include <TDataXtd_Constraint.hxx>
70 #include <TDataXtd_Geometry.hxx>
71 #include <TDF_Label.hxx>
72 #include <TDF_Reference.hxx>
73 #include <TNaming_Iterator.hxx>
74 #include <TNaming_NamedShape.hxx>
75 #include <TNaming_Tool.hxx>
76 #include <TopExp.hxx>
77 #include <TopExp_Explorer.hxx>
78 #include <TopoDS.hxx>
79 #include <TopoDS_Edge.hxx>
80 #include <TopoDS_Face.hxx>
81 #include <TopoDS_Shape.hxx>
82 #include <TopoDS_Vertex.hxx>
83 #include <TopTools_IndexedMapOfShape.hxx>
84 #include <UnitsAPI.hxx>
85
86 #include <stdio.h>
87 static Standard_Boolean CheckShapesPair(const TopoDS_Shape& , const TopoDS_Shape& ); //ota
88
89 //=======================================================================
90 //function : static NullifyAIS
91 //purpose  : 
92 //=======================================================================
93 static void NullifyAIS ( Handle(AIS_InteractiveObject)& anais)
94 {
95   if (anais.IsNull())  return;
96   anais.Nullify();
97 }
98
99
100
101 //=======================================================================
102 //function : static FindExternalShape
103 //purpose  : 
104 //=======================================================================
105 static void FindExternalShape(const Handle(TDataXtd_Constraint)& aConst,
106                               Standard_Integer& extShape)
107 {
108   extShape = 0;
109     const TDF_Label& L =  aConst->Label();
110     if (!aConst->GetGeometry(1)->Label().IsDescendant(L)) extShape = 1;    
111     else if (!aConst->GetGeometry(2)->Label().IsDescendant(L)) extShape = 2;
112 }
113
114 //=======================================================================
115 //function : static GetGoodShape for planar constraint
116 //purpose  : 
117 //=======================================================================
118 static void  GetGoodShape(TopoDS_Shape& theShape)
119 {
120   switch (theShape.ShapeType())
121   {
122   case TopAbs_EDGE:
123   case TopAbs_VERTEX: { return; }
124   default:
125     {
126       TopExp_Explorer anExp (theShape,TopAbs_EDGE);
127       if (anExp.More())
128       {
129         theShape = anExp.Current();
130         return;
131       }
132       else
133       {
134         anExp.Init (theShape, TopAbs_VERTEX);
135         if (anExp.More())
136         {
137           theShape = anExp.Current();
138         }
139       }
140     }
141   }
142 }
143
144 // Pour le cas ou S est un compound
145 static Standard_Boolean IsFace (const TopoDS_Shape& S)
146 {
147   Standard_Boolean  findface = Standard_False;
148   TopExp_Explorer EXP (S,TopAbs_FACE);
149   if (EXP.More()) findface = Standard_True;
150   return  findface;
151 }
152
153 static TopoDS_Face  GetFace (const TopoDS_Shape& S)
154 {
155   TopoDS_Face F;
156   TopExp_Explorer EXP (S,TopAbs_FACE);
157   if (EXP.More())  F = TopoDS::Face (EXP.Current());
158   return  F;
159 }
160
161 static TopoDS_Edge  GetEdge (const TopoDS_Shape& S)
162 {
163   TopoDS_Edge E;
164   TopExp_Explorer EXP (S, TopAbs_EDGE);
165   if (EXP.More()) E = TopoDS::Edge (EXP.Current());
166   return  E;
167 }
168
169
170
171 //=======================================================================
172 //Function : ComputeAndTextValue
173 //purpose  : 
174 //=======================================================================
175 void TPrsStd_ConstraintTools::ComputeTextAndValue(const Handle(TDataXtd_Constraint)& aConst,
176                                                  Standard_Real&                val,
177                                                  TCollection_ExtendedString&   txt,
178                                                  const Standard_Boolean  anIsAngle  )
179 {
180   Standard_Real outvalue;
181   const Handle(TDataStd_Real)& VAL = aConst->GetValue();
182   val      = VAL->Get();
183   if(anIsAngle){
184     outvalue = UnitsAPI::CurrentFromLS(Abs(val),"PLANE ANGLE");
185   }
186   else {
187     outvalue = UnitsAPI::CurrentFromLS(val,"LENGTH");
188   }
189   char res[1000];
190   sprintf(res,"%g",outvalue);
191   txt = TCollection_ExtendedString(res);
192   
193   if (VAL->IsCaptured()) {
194     Handle(TDF_Reference) ref;
195     VAL->Label().FindAttribute(TDF_Reference::GetID(),ref);
196     Handle(TDataStd_Name) name;
197     const TDF_Label& L = ref->Get();
198     if (ref->Get().FindAttribute(TDataStd_Name::GetID(),name)) {
199       TCollection_ExtendedString fullname;
200       Handle(TDataStd_Name) Fathername;
201       if (L.Father().FindAttribute(TDataStd_Name::GetID(),Fathername)) {
202         fullname = Fathername->Get() + TCollection_ExtendedString(".") + name->Get();
203       }
204       else fullname = name->Get();
205       txt = fullname + TCollection_ExtendedString("=") + txt;
206     }
207   }
208 }
209
210
211 //=======================================================================
212 //function : UpdateOnlyValue
213 //purpose  : 
214 //=======================================================================
215
216 void TPrsStd_ConstraintTools::UpdateOnlyValue(const Handle(TDataXtd_Constraint)& aConst, 
217                                      const Handle(AIS_InteractiveObject)& anAIS)
218 {
219   if (anAIS.IsNull()) return; 
220   if (!aConst->IsDimension()) return; 
221   Standard_Real val;
222   TCollection_ExtendedString txt;
223   TPrsStd_ConstraintTools:: ComputeTextAndValue(aConst,val,txt,aConst->GetType() == TDataXtd_ANGLE);
224   Handle(PrsDim_Relation) rel = Handle(PrsDim_Relation)::DownCast(anAIS);
225   if (!rel.IsNull()) rel->SetText(txt); 
226 }
227
228
229 //=======================================================================
230 //function : ComputeDistance
231 //purpose  : Build an AIS_LengthDimension.
232 //=======================================================================
233 void TPrsStd_ConstraintTools::ComputeDistance (const Handle(TDataXtd_Constraint)& theConst,
234                                                Handle(AIS_InteractiveObject)&     theAIS)
235 {
236   Standard_Integer aGeomNum = theConst->NbGeometries();
237
238   // Dimension is build on one or two shapes.
239   if (aGeomNum < 1 || aGeomNum > 2)
240   {
241 #ifdef OCCT_DEBUG
242     std::cout <<  "TPrsStd_ConstraintTools::ComputeDistance: 1 or 2 geometries are needed" << std::endl;
243 #endif
244     NullifyAIS(theAIS);
245     return;
246   }
247
248   TopoDS_Shape aShape1, aShape2;
249   Handle(Geom_Geometry) aGeom3;
250   Standard_Boolean isPlanar (theConst->IsPlanar());
251
252   // Get shapes and geometry
253   if (aGeomNum == 1)
254   {
255     GetOneShape (theConst, aShape1);
256
257     if (aShape1.IsNull())
258     {
259       #ifdef OCCT_DEBUG
260       std::cout << "TPrsStd_ConstraintTools::ComputeDistance : null shape" << std::endl;
261       #endif
262       NullifyAIS (theAIS);
263       return;
264     }
265   }
266   else //aGeomNum == 2
267   {
268     GetTwoShapes (theConst, aShape1, aShape2);
269
270     if (aShape1.IsNull() || aShape2.IsNull())
271     {
272       #ifdef OCCT_DEBUG
273       std::cout << "TPrsStd_ConstraintTools::ComputeDistance : null shape" << std::endl;
274       #endif
275       NullifyAIS (theAIS);
276       return;
277     }
278   }
279
280   // Get plane from constraint
281   Handle(Geom_Plane) aPlane;
282   if (isPlanar)
283   {
284     GetGeom (theConst, aGeom3);
285
286     GetGoodShape (aShape1);
287
288     if (aGeomNum == 2)
289     {
290       GetGoodShape (aShape2);
291     }
292
293     aPlane = Handle(Geom_Plane)::DownCast (aGeom3);
294   }
295
296   // Get custom value
297   Standard_Real aValue;
298   TCollection_ExtendedString aText;
299   ComputeTextAndValue (theConst, aValue, aText,Standard_False);
300
301   Standard_Boolean isFaces     = Standard_False;
302   Standard_Boolean isEdges     = Standard_False;
303   Standard_Boolean isEdgeFace  = Standard_False;
304   Standard_Boolean isVertices  = Standard_False;
305   Standard_Boolean isEdge      = Standard_False;
306
307   Standard_Boolean SaveDrw = Standard_False;
308   Handle(Prs3d_Drawer) aDrawer;
309   Handle(PrsDim_LengthDimension) aDim;
310
311   if (!theAIS.IsNull())
312   {
313     aDim = Handle(PrsDim_LengthDimension)::DownCast (theAIS);
314   }
315
316   // Check shapes for AIS dimension
317   if (aGeomNum == 1)
318   {
319     if (aShape1.ShapeType () != TopAbs_EDGE)
320     {
321       #ifdef OCCT_DEBUG
322       std::cout << "TPrsStd_ConstraintTools::ComputeDistance : shape should be edge" << std::endl;
323       #endif
324       NullifyAIS (theAIS);
325       return;
326     }
327
328     isEdge = Standard_True;
329   }
330   else // nbgeom == 2
331   {
332     isFaces      = IsFace (aShape1) && IsFace (aShape2);
333
334     isEdges      = (aShape1.ShapeType() == TopAbs_EDGE) && (aShape2.ShapeType() == TopAbs_EDGE);
335
336     isEdgeFace   = ((aShape1.ShapeType() == TopAbs_FACE) && (aShape2.ShapeType() == TopAbs_EDGE))
337                    || ((aShape1.ShapeType() == TopAbs_EDGE) && (aShape2.ShapeType() == TopAbs_FACE));
338
339     isVertices  = (aShape1.ShapeType() == TopAbs_VERTEX) && (aShape2.ShapeType() == TopAbs_VERTEX);
340
341     if (!isPlanar && !isFaces && !isEdges && !isVertices)
342     {
343       // Search suitable geometry for dimension
344       if (aShape1.ShapeType() == aShape2.ShapeType())
345       {
346         TopoDS_Vertex aV1, aV2, aV3, aV4;
347         if (aShape1.ShapeType() == TopAbs_WIRE)
348         {
349           TopExp::Vertices (TopoDS::Wire(aShape1), aV1, aV2);
350           TopExp::Vertices (TopoDS::Wire(aShape2), aV3, aV4);
351         }
352         aShape1 = aV1;
353         gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
354         gp_Pnt aP2 = BRep_Tool::Pnt(aV3);
355         gp_Pnt aP3 = BRep_Tool::Pnt (aV4);
356         if (aP1.Distance (aP2) < aP1.Distance (aP3))
357         {
358           aShape2 = aV3;
359           gp_Ax2 ax2 (aP1, gp_Dir (aP2.XYZ() - aP1.XYZ()));
360           aPlane = new Geom_Plane (aP1, ax2.XDirection());
361         }
362         else
363         {
364           aShape2 = aV4;
365           gp_Ax2 anAx2 (aP1, gp_Dir (aP3.XYZ() - aP1.XYZ()));
366           aPlane = new Geom_Plane (aP1, anAx2.XDirection());
367         }
368       }
369       else if (!isEdgeFace)
370       {
371         NullifyAIS (theAIS);
372         return;
373       }
374     }
375   }
376
377   // Check plane
378   Standard_Boolean isCheckPlane = (aDim.IsNull() && !isFaces) || isPlanar;
379   if ((isVertices || isEdges) && !isPlanar)
380   {
381     gp_Pnt aP1, aP2, aP3;
382
383     if (isVertices)
384     {
385       aP1 = BRep_Tool::Pnt (TopoDS::Vertex (aShape1));
386       aP2 = BRep_Tool::Pnt (TopoDS::Vertex (aShape2));
387       aP3 = gp_Pnt (aP1.Y() - 1.0, aP2.X() + 1.0, 0.0);
388     }
389
390     if (isEdges)
391     {
392       TopoDS_Vertex  aV1, aV2, aV3, aV4;
393       TopExp::Vertices (TopoDS::Edge(aShape1), aV1, aV2);
394       TopExp::Vertices (TopoDS::Edge(aShape2), aV3, aV4);
395       aP1 = BRep_Tool::Pnt (aV1);
396       aP2 = BRep_Tool::Pnt (aV2);
397       aP3 = BRep_Tool::Pnt (aV3);
398     }
399
400     GC_MakePlane aPlaneMaker (aP1, aP2, aP3);
401     if (aPlaneMaker.IsDone() && !isPlanar)
402     {
403       aPlane = aPlaneMaker.Value();
404     }
405   }
406
407   if (isCheckPlane && aPlane.IsNull())
408   {
409     #ifdef OCCT_DEBUG
410     std::cout << "TPrsStd_ConstraintTools::ComputeDistance : null plane" << std::endl;
411     #endif
412     NullifyAIS (theAIS);
413     return;
414   }
415
416   //  Update of AIS
417   if (aDim.IsNull())
418   {
419     if (isEdge)
420     {
421       aDim = new PrsDim_LengthDimension (GetEdge (aShape1), aPlane->Pln());
422     }
423     else if (isFaces)
424     {
425       aDim = new PrsDim_LengthDimension (GetFace (aShape1), GetFace (aShape2));
426     }
427     else
428     {
429       aDim = new PrsDim_LengthDimension (aShape1, aShape2, aPlane->Pln());
430     }
431
432     if (SaveDrw)
433     {
434         aDim->SetAttributes (aDrawer);
435     }
436   }
437   else
438   {
439     if (isEdge)
440     {
441       aDim->SetMeasuredGeometry (GetEdge(aShape1), aPlane->Pln());
442     }
443     else
444     {
445       aDim->SetMeasuredShapes (aShape1, aShape2);
446     }
447
448     aDim->SetCustomValue (aValue);
449   }
450
451   if (!aPlane.IsNull())
452   {
453     aDim->SetCustomPlane (aPlane->Pln());
454   }
455
456   theAIS = aDim;
457 }
458
459 //=======================================================================
460 //function : ComputePerpendicular
461 //purpose  : 
462 //=======================================================================
463 void TPrsStd_ConstraintTools::ComputePerpendicular(const Handle(TDataXtd_Constraint)& aConst,
464                                                   Handle(AIS_InteractiveObject)& anAIS) 
465 {
466   Standard_Integer nbgeom = aConst->NbGeometries();
467   if (nbgeom < 2) {
468 #ifdef OCCT_DEBUG
469     std::cout << "TPrsStd_ConstraintTools::ComputePerpendicular: at leat two constraintes are needed" << std::endl;
470 #endif
471     NullifyAIS(anAIS);
472     return;
473   }
474   
475   TopoDS_Shape shape1,shape2 ;
476   Handle(Geom_Geometry) ageom3;
477   Standard_Boolean is_planar(aConst->IsPlanar());
478   
479   if (is_planar) GetShapesAndGeom(aConst,shape1,shape2,ageom3);
480   else GetTwoShapes(aConst,shape1,shape2); 
481   if (shape1.IsNull() || shape2.IsNull()) {
482 #ifdef OCCT_DEBUG
483     std::cout << "TPrsStd_ConstraintTools::ComputePerpendicular : null shape" << std::endl;
484 #endif
485     NullifyAIS(anAIS);
486     return;
487   }
488   GetGoodShape(shape1);
489   GetGoodShape(shape2);
490   //  Update de l'AIS
491   Handle(PrsDim_PerpendicularRelation) ais;
492   if (anAIS.IsNull()) ais = new PrsDim_PerpendicularRelation(shape1,shape2);
493   else {
494     ais = Handle(PrsDim_PerpendicularRelation)::DownCast(anAIS);
495     if (ais.IsNull()) {
496       ais = new PrsDim_PerpendicularRelation(shape1,shape2);
497     }
498     else {
499       ais->SetFirstShape(shape1);
500       ais->SetSecondShape(shape2);
501     }
502   }
503   
504   if (is_planar) {
505     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
506     if (aplane.IsNull()) {
507 #ifdef OCCT_DEBUG
508       std::cout << "TPrsStd_ConstraintTools::ComputePerpendicular: nul plane" << std::endl;
509 #endif
510       NullifyAIS(anAIS);
511       return;
512     }
513     ais->SetPlane(aplane);
514   }
515   anAIS = ais;
516 }
517
518 //=======================================================================
519 //function : ComputeParallel
520 //purpose  : 
521 //=======================================================================
522 void TPrsStd_ConstraintTools::ComputeParallel(const Handle(TDataXtd_Constraint)& aConst, 
523                                              Handle(AIS_InteractiveObject)& anAIS) 
524 {
525   Standard_Integer nbgeom = aConst->NbGeometries();
526   if (nbgeom < 2) {
527 #ifdef OCCT_DEBUG
528     std::cout << "TPrsStd_ConstraintTools::ComputeParallel: at least 2 constraintes are needed" << std::endl;
529 #endif
530     NullifyAIS(anAIS);
531     return;
532   }
533   
534   if (!aConst->IsPlanar()) {
535 #ifdef OCCT_DEBUG
536     std::cout << "TPrsStd_ConstraintTools::ComputeParallel: must be a planar constraint" << std::endl;
537 #endif
538     NullifyAIS(anAIS);
539     return;
540   }
541
542   TopoDS_Shape shape1,shape2 ;
543   Handle(Geom_Geometry) ageom3;
544   
545   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
546   if (shape1.IsNull() || shape2.IsNull()) {
547 #ifdef OCCT_DEBUG
548     std::cout << "TPrsStd_ConstraintTools::ComputeParallel : null shape" << std::endl;
549 #endif
550     NullifyAIS(anAIS);
551     return;
552   }
553   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
554   if (aplane.IsNull()) {
555 #ifdef OCCT_DEBUG
556     std::cout << "TPrsStd_ConstraintTools::ComputeParallel: nul plane" << std::endl;
557 #endif
558     NullifyAIS(anAIS);
559     return;
560   }
561   //  Update de l'AIS
562   GetGoodShape(shape1);
563   GetGoodShape(shape2);
564   Handle(PrsDim_ParallelRelation) ais;
565   if (anAIS.IsNull()) ais = new PrsDim_ParallelRelation(shape1,shape2,aplane);
566   else { 
567     ais = Handle(PrsDim_ParallelRelation)::DownCast(anAIS);
568     if (ais.IsNull()) {
569       ais = new PrsDim_ParallelRelation(shape1,shape2,aplane);
570     }
571     else {
572       ais->SetFirstShape(shape1);
573       ais->SetSecondShape(shape2);
574       ais->SetPlane(aplane);
575     }
576   }
577   anAIS = ais;
578 }
579 //=======================================================================
580 //function : ComputeSymmetry
581 //purpose  : 
582 //=======================================================================
583 void TPrsStd_ConstraintTools::ComputeSymmetry(const Handle(TDataXtd_Constraint)& aConst,
584                                              Handle(AIS_InteractiveObject)& anAIS) 
585 {
586   Standard_Integer nbgeom = aConst->NbGeometries();
587   if (nbgeom < 3) {
588 #ifdef OCCT_DEBUG
589     std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry: at least 3 constraintes are needed" << std::endl;
590 #endif
591     NullifyAIS(anAIS);
592     return;
593   }
594
595   Standard_Boolean is_planar(aConst->IsPlanar());
596   if (!is_planar) {
597 #ifdef OCCT_DEBUG
598     std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry: must be a planar constraint" << std::endl;
599 #endif
600     NullifyAIS(anAIS);
601     return;
602   }
603
604   TopoDS_Shape shape1,shape2,shape3 ;
605   Handle(Geom_Geometry) ageom3;
606   GetShapesAndGeom(aConst,shape1,shape2,shape3,ageom3);
607
608   if (shape1.IsNull() || shape2.IsNull() || shape3.IsNull()) {
609 #ifdef OCCT_DEBUG
610     std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry : null shape" << std::endl;
611 #endif
612     NullifyAIS(anAIS);
613     return;
614   }
615   GetGoodShape(shape1);
616   GetGoodShape(shape2);
617   GetGoodShape(shape3);
618   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
619   if (aplane.IsNull()) {
620 #ifdef OCCT_DEBUG
621     std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry: null plane" << std::endl;
622 #endif
623     NullifyAIS(anAIS);
624     return;
625   }
626   //  Update de l'AIS
627   Handle(PrsDim_SymmetricRelation) ais;
628   if (anAIS.IsNull()) ais = new PrsDim_SymmetricRelation(shape3,shape1,shape2,aplane);
629   else {
630     ais = Handle(PrsDim_SymmetricRelation)::DownCast(anAIS);
631     if (ais.IsNull()) {
632       ais = new PrsDim_SymmetricRelation(shape3,shape1,shape2,aplane);
633     }
634     else {
635       ais->SetFirstShape(shape1);
636       ais->SetSecondShape(shape2);
637       ais->SetPlane(aplane);
638       ais->SetTool(shape3);
639     }
640   }
641   anAIS = ais;
642 }
643
644 //=======================================================================
645 //function : ComputeMidPoint
646 //purpose  : 
647 //=======================================================================
648 void TPrsStd_ConstraintTools::ComputeMidPoint(const Handle(TDataXtd_Constraint)& aConst,
649                                               Handle(AIS_InteractiveObject)& anAIS) 
650 {
651   Standard_Integer nbgeom = aConst->NbGeometries();
652   if (nbgeom < 3)
653     {
654 #ifdef OCCT_DEBUG
655       std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry: at least 3 constraints are needed" << std::endl;
656 #endif
657       NullifyAIS(anAIS);
658       return;
659     }
660
661   Standard_Boolean is_planar(aConst->IsPlanar());
662   if ( !is_planar )
663     {
664 #ifdef OCCT_DEBUG
665       std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry: must be a planar constraint" << std::endl;
666 #endif
667       NullifyAIS(anAIS);
668       return;
669     }
670
671   TopoDS_Shape shape1,shape2,shape3;
672   Handle(Geom_Geometry) ageom3;
673   GetShapesAndGeom(aConst,shape1,shape2,shape3,ageom3);
674
675   if (shape1.IsNull() || shape2.IsNull() || shape3.IsNull())
676     {
677 #ifdef OCCT_DEBUG
678       std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry : null shape" << std::endl;
679 #endif
680       NullifyAIS(anAIS);
681       return;
682     }
683   GetGoodShape(shape1);
684   GetGoodShape(shape2);
685   GetGoodShape(shape3);
686
687   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
688   if (aplane.IsNull())
689     {
690 #ifdef OCCT_DEBUG
691       std::cout << "TPrsStd_ConstraintTools::ComputeSymmetry: null plane" << std::endl;
692 #endif
693       NullifyAIS(anAIS);
694       return;
695     }
696
697   //  Update de l'AIS
698   Handle(PrsDim_MidPointRelation) ais;
699   if ( anAIS.IsNull() ) ais = new PrsDim_MidPointRelation(shape3,shape1,shape2,aplane);
700   else
701     {
702       ais = Handle(PrsDim_MidPointRelation)::DownCast(anAIS);
703       if (ais.IsNull())
704         {
705           ais = new PrsDim_MidPointRelation(shape3,shape1,shape2,aplane);
706         }
707       else
708         {
709           ais->SetFirstShape(shape1);
710           ais->SetSecondShape(shape2);
711           ais->SetPlane(aplane);
712           ais->SetTool(shape3);
713         }
714     }
715   anAIS = ais;
716 }
717
718 //=======================================================================
719 //function : ComputeTangent
720 //purpose  : 
721 //=======================================================================
722 void TPrsStd_ConstraintTools::ComputeTangent (const Handle(TDataXtd_Constraint)& aConst, 
723                                              Handle(AIS_InteractiveObject)& anAIS) 
724 {
725   Standard_Integer nbgeom = aConst->NbGeometries();
726   if (nbgeom < 2) {
727 #ifdef OCCT_DEBUG
728     std::cout << "TPrsStd_ConstraintTools::ComputeTangent: at leat two constraintes are needed" << std::endl;
729 #endif
730     NullifyAIS(anAIS);
731     return;
732   }
733   if (!aConst->IsPlanar()) {
734 #ifdef OCCT_DEBUG
735     std::cout << "TPrsStd_ConstraintTools::ComputeTangent: must be a planar constraint" << std::endl;
736 #endif
737     NullifyAIS(anAIS);
738     return;
739   }
740   TopoDS_Shape shape1,shape2 ;
741   Handle(Geom_Geometry) ageom3;
742   
743   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
744   if (shape1.IsNull() || shape2.IsNull()) {
745 #ifdef OCCT_DEBUG
746     std::cout << "TPrsStd_ConstraintTools::ComputeTangent : null shape" << std::endl;
747 #endif
748     NullifyAIS(anAIS);
749     return;
750   }
751   GetGoodShape(shape1);
752   GetGoodShape(shape2);
753   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
754   if (aplane.IsNull()) {
755 #ifdef OCCT_DEBUG
756     std::cout << "TPrsStd_ConstraintTools::ComputeTangent: nul plane" << std::endl;
757 #endif
758     NullifyAIS(anAIS);
759     return;    
760   }
761   //  Update de l'AIS
762   Handle(PrsDim_TangentRelation) ais;
763   if (anAIS.IsNull())
764     {
765       ais = new PrsDim_TangentRelation(shape1,shape2,aplane);
766       ais->SetArrowSize(10000000); // jfa 9/10/2000
767     }
768   else
769     {
770       ais = Handle(PrsDim_TangentRelation)::DownCast(anAIS);
771       if (ais.IsNull())
772         {
773           ais = new PrsDim_TangentRelation(shape1,shape2,aplane);
774           ais->SetArrowSize(10000000); // jfa 9/10/2000
775         }
776       else
777         {
778           ais->SetFirstShape(shape1);
779           ais->SetSecondShape(shape2);
780           ais->SetPlane(aplane);
781           ais->SetArrowSize(10000000); // jfa 9/10/2000
782         }
783     }
784   anAIS = ais;
785 }
786
787 //=======================================================================
788 //function : ComputeAngleForOneFace
789 //purpose  : computes AngleDimension for one-conical-face case
790 //=======================================================================
791 void TPrsStd_ConstraintTools::ComputeAngleForOneFace (const Handle(TDataXtd_Constraint)& aConst,
792                                            Handle(AIS_InteractiveObject)& anAIS) 
793 {
794  
795   TopoDS_Shape shape;
796   Handle(Geom_Geometry) ageom3;
797   
798   GetOneShape( aConst, shape ); 
799   if (shape.IsNull() ) {
800 #ifdef OCCT_DEBUG
801     std::cout << "TPrsStd_ConstraintTools::ComputeAngleForOneFace : null shape" << std::endl;
802 #endif
803     NullifyAIS(anAIS);
804     return;
805   }
806
807   Standard_Real val1;
808   TCollection_ExtendedString txt;
809   TPrsStd_ConstraintTools::ComputeTextAndValue (aConst,val1,txt,Standard_True);  
810   
811   Handle(PrsDim_AngleDimension) ais;
812   TopoDS_Face face;
813   if (!anAIS.IsNull()) {
814     ais = Handle(PrsDim_AngleDimension)::DownCast(anAIS);
815     if(ais.IsNull()) {
816       face = TopoDS::Face( shape );
817       ais =  new PrsDim_AngleDimension (face);
818     }
819     else {
820       ais->SetMeasuredGeometry(TopoDS::Face( shape ));
821     }
822   }
823   else {
824     face = TopoDS::Face (shape);
825     ais =  new PrsDim_AngleDimension (face);
826   } 
827
828   anAIS = ais;
829 }
830
831 //=======================================================================
832 //function : CheckIsShapeCompound
833 //purpose  : 
834 //=======================================================================
835
836 static Standard_Boolean CheckIsShapeCompound(TopoDS_Shape& shape, TopoDS_Face& aFace)
837 {
838   if (shape.ShapeType() == TopAbs_COMPOUND) {
839     TopTools_IndexedMapOfShape aFaceMap;
840     TopExp::MapShapes(shape, TopAbs_FACE, aFaceMap);
841     for(Standard_Integer i = 1;i <= aFaceMap.Extent();i++) 
842       {
843         aFace = TopoDS::Face(aFaceMap.FindKey(i));
844         if(!aFace.IsNull()) {
845           shape = aFace;
846           return (Standard_True);
847         }
848       }
849   }
850 #ifdef OCCT_DEBUG
851   std::cout << "TPrsStd::Compute angle : Shape is not Compound or is Null" <<std::endl;
852 #endif
853   return (Standard_False);
854 }
855
856 //=======================================================================
857 //function : ComputeAngle
858 //purpose  : 
859 //=======================================================================
860
861 void TPrsStd_ConstraintTools::ComputeAngle (const Handle(TDataXtd_Constraint)& aConst,
862                                            Handle(AIS_InteractiveObject)& anAIS) 
863 {
864   Standard_Integer nbgeom = aConst->NbGeometries();
865   if (nbgeom < 2) {
866     if( nbgeom == 1 ) { ComputeAngleForOneFace( aConst, anAIS ); return; }
867 #ifdef OCCT_DEBUG
868     std::cout << "TPrsStd_ConstraintTools::ComputeAngle: at least 2 constraints are needed" << std::endl;
869 #endif
870     NullifyAIS(anAIS);
871     return;
872   }
873   
874   TopoDS_Shape shape1,shape2 ;
875   Handle(Geom_Geometry) ageom3;
876   
877   GetShapesAndGeom (aConst,shape1,shape2,ageom3);
878   if (shape1.IsNull() || shape2.IsNull()) {
879 #ifdef OCCT_DEBUG
880     std::cout << "TPrsStd_ConstraintTools::ComputeAngle : null shape" << std::endl;
881 #endif
882     NullifyAIS(anAIS);
883     return;
884   }
885   
886   Standard_Boolean isCurvilinear = Standard_False;
887   if (ageom3.IsNull()) {
888     // on essaie de le calculer
889     
890     TopoDS_Face  aFace;
891     if (shape1.ShapeType() == TopAbs_WIRE)  {
892       BRepBuilderAPI_MakeFace MkF (TopoDS::Wire(shape1),Standard_True);
893       if (MkF.IsDone())  {
894         aFace = MkF.Face();
895         shape1 = aFace;
896       }
897     }
898     else
899       if (shape1.ShapeType() == TopAbs_FACE)
900         aFace    = TopoDS::Face(shape1);
901       else
902         if(!CheckIsShapeCompound(shape1, aFace)) {
903 #ifdef OCCT_DEBUG
904         std::cout << "Compute angle : Geom type = " << shape1.ShapeType()
905           << " non traite"<<std::endl;
906 #endif
907         NullifyAIS(anAIS);
908         return;      
909       }
910
911     gp_Ax1 anax1aFace1;
912     gp_Pln aPlnaFace1;
913
914     BRepAdaptor_Surface   aSurfaFace (aFace);
915     GeomAbs_SurfaceType aTypeaFace = aSurfaFace.GetType();
916     if (aTypeaFace  == GeomAbs_Plane) {
917       aPlnaFace1 = aSurfaFace.Plane();
918       anax1aFace1 = aPlnaFace1.Axis(); // Normale au plan
919     } else if (aTypeaFace  == GeomAbs_Cylinder) {
920       gp_Cylinder aCylaFace = aSurfaFace.Cylinder();
921       anax1aFace1 = aCylaFace.Axis();
922     } else if (aTypeaFace  == GeomAbs_Cone) {
923       gp_Cone aCone = aSurfaFace.Cone();
924       anax1aFace1 = aCone.Axis();  
925     } else if (aTypeaFace  == GeomAbs_Torus) {
926       gp_Torus aTore = aSurfaFace.Torus();
927       anax1aFace1 = aTore.Axis();  
928     } else {
929 #ifdef OCCT_DEBUG
930       std::cout<<"Compute angle"<<aTypeaFace<<" non traite"<<std::endl;
931 #endif
932       NullifyAIS(anAIS);
933       return;      
934     }
935
936     gp_Ax1 anax1aFace2;
937     gp_Pln aPlnaFace2;
938     if (shape2.ShapeType() == TopAbs_WIRE)  {
939       BRepBuilderAPI_MakeFace MkF (TopoDS::Wire(shape2),Standard_True);
940       if (MkF.IsDone())  {
941         aFace = MkF.Face();
942         shape2 = aFace;
943       }
944     }
945     else
946       if (shape2.ShapeType() == TopAbs_FACE)
947         aFace    = TopoDS::Face(shape2); 
948     else  
949       if(!CheckIsShapeCompound(shape2, aFace)) {
950 #ifdef OCCT_DEBUG
951         std::cout << "Compute angle : Geom type = " << shape2.ShapeType()
952           << " non traite"<<std::endl;
953 #endif
954         NullifyAIS(anAIS);
955         return;      
956       }
957     
958     aSurfaFace.Initialize(aFace);
959     aTypeaFace = aSurfaFace.GetType();
960     if (aTypeaFace  == GeomAbs_Plane) {
961       aPlnaFace2 = aSurfaFace.Plane();
962       anax1aFace2 = aPlnaFace2.Axis(); // Normale au plan
963     } else if (aTypeaFace  == GeomAbs_Cylinder) {
964       gp_Cylinder aCylaFace = aSurfaFace.Cylinder();
965       anax1aFace2 = aCylaFace.Axis();
966     } else if (aTypeaFace  == GeomAbs_Cone) {
967       gp_Cone aCone = aSurfaFace.Cone();
968       anax1aFace2 = aCone.Axis();  
969     } else if (aTypeaFace  == GeomAbs_Torus) {
970       gp_Torus aTore = aSurfaFace.Torus();
971       anax1aFace2 = aTore.Axis();  
972     } else {
973 #ifdef OCCT_DEBUG
974       std::cout << "Compute angle " << aTypeaFace << " non traite"<<std::endl;
975 #endif
976       NullifyAIS(anAIS);
977       return;      
978     }
979
980     if (aTypeaFace==GeomAbs_Plane) {
981       if (!anax1aFace1.IsParallel(anax1aFace2, Precision::Angular())) {
982         
983         IntAna_QuadQuadGeo IntersectPlane (aPlnaFace1, aPlnaFace2, Precision::Angular(), Precision::Angular());
984         if (IntersectPlane.IsDone() &&
985             (IntersectPlane.TypeInter() != IntAna_Empty))  {
986           gp_Lin aLine = IntersectPlane.Line(1);
987           Handle(Geom_Line) computedgeom3 = new Geom_Line (aLine);
988           ageom3 = computedgeom3;
989         } else {
990 #ifdef OCCT_DEBUG
991           std::cout<<"Compute angle insertection of planes failed"<<std::endl;
992 #endif
993           NullifyAIS(anAIS);
994           return;            
995         }
996       } else {
997         
998 #ifdef OCCT_DEBUG
999         std::cout<<"Compute angle faces are //"<<std::endl;
1000 #endif
1001         NullifyAIS(anAIS);
1002         return;            
1003       }
1004     } else {
1005       // Curvilinear faces...
1006       isCurvilinear = Standard_True;
1007     }
1008   } // endif (ageom3.IsNull())
1009
1010
1011   Standard_Boolean isplan(Standard_False);
1012
1013   if (!isCurvilinear) {
1014     if (ageom3->IsKind(STANDARD_TYPE(Geom_Plane))) isplan = Standard_True;
1015     else if (ageom3->IsKind(STANDARD_TYPE(Geom_Line))) isplan = Standard_False;
1016     else {
1017 #ifdef OCCT_DEBUG
1018       std::cout << "TPrsStd_ConstraintTools::ComputeAngle: unknown 3rd arg " << std::endl;
1019 #endif
1020       NullifyAIS(anAIS);
1021       return;
1022     }
1023   }
1024   Standard_Real val1;
1025   TCollection_ExtendedString txt;
1026   ComputeTextAndValue (aConst,val1,txt,Standard_True);  
1027   
1028   Standard_Boolean toCreate (Standard_True);
1029   Standard_Boolean isface(shape1.ShapeType()==TopAbs_FACE);
1030   
1031   Handle(PrsDim_AngleDimension) ais;
1032   if (!anAIS.IsNull()) {
1033     ais = Handle(PrsDim_AngleDimension)::DownCast(anAIS);
1034     if( ais.IsNull() ) {
1035       toCreate = Standard_True;
1036     }
1037     else toCreate = Standard_False;
1038   }
1039   
1040   Standard_Integer ExtShape(0);
1041   if (toCreate)  {
1042     // Creation de l'AIS
1043     if (isplan) {
1044       if(!isface) {
1045         FindExternalShape(aConst,ExtShape);
1046         GetGoodShape(shape1);
1047         GetGoodShape(shape2);
1048         ais = new PrsDim_AngleDimension (TopoDS::Edge(shape1),
1049                                       TopoDS::Edge(shape2));
1050       }
1051     }
1052     else { 
1053       if (isCurvilinear) {
1054   ais = new PrsDim_AngleDimension (TopoDS::Face(shape1),
1055                                 TopoDS::Face(shape2));
1056       }
1057       else if (isface) {
1058   ais =  new PrsDim_AngleDimension (TopoDS::Face(shape1),
1059                                  TopoDS::Face(shape2));
1060       }
1061     }
1062   }
1063   else {
1064     // Update de l'AIS
1065     if (isplan) {
1066       GetGoodShape(shape1);
1067       GetGoodShape(shape2);
1068     }
1069     ais->SetMeasuredGeometry (TopoDS::Face (shape1), TopoDS::Face (shape2));
1070     if (isplan)
1071       ais->SetCustomPlane (Handle(Geom_Plane)::DownCast (ageom3)->Pln());
1072     else if (!isCurvilinear)
1073     {
1074       gp_Pln aPlane;
1075       aPlane.SetAxis (Handle(Geom_Line)::DownCast (ageom3)->Position());
1076       ais->SetCustomPlane (aPlane);
1077     }
1078   }
1079   anAIS = ais;
1080 }
1081
1082
1083 //=======================================================================
1084 //function : ComputeConcentric
1085 //purpose  : 
1086 //=======================================================================
1087 void TPrsStd_ConstraintTools::ComputeConcentric(const Handle(TDataXtd_Constraint)& aConst,
1088                                                Handle(AIS_InteractiveObject)& anAIS) 
1089 {
1090   Standard_Integer nbgeom = aConst->NbGeometries();
1091   if (nbgeom < 2) {
1092     throw Standard_ProgramError("TPrsStd_ConstraintTools::ComputeConcentric: at least 2 constraintes are needed");
1093   }
1094   if (!aConst->IsPlanar()) {
1095 #ifdef OCCT_DEBUG
1096     std::cout << "TPrsStd_ConstraintTools::ComputeConcentric: must be a planar constraint" << std::endl;
1097 #endif
1098     NullifyAIS(anAIS);
1099     return;
1100   }
1101   TopoDS_Shape shape1,shape2 ;
1102   Handle(Geom_Geometry) ageom3;
1103   
1104   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
1105   if (shape1.IsNull() || shape2.IsNull()) {
1106 #ifdef OCCT_DEBUG
1107     std::cout << "TPrsStd_ConstraintTools::ComputeConcentric : null shape" << std::endl;
1108 #endif
1109     NullifyAIS(anAIS);
1110     return;
1111   }
1112
1113   GetGoodShape(shape1);
1114   GetGoodShape(shape2);
1115
1116 //ota : to allow concentric constraint display between vertex and edge
1117   if (shape1.ShapeType() != TopAbs_EDGE && shape2.ShapeType() != TopAbs_EDGE) {
1118 #ifdef OCCT_DEBUG
1119     std::cout << "TPrsStd_ConstraintTools::ComputeConcentric: concentric between two vertexes : NOT DISPLAYED" << std::endl;
1120 #endif
1121     NullifyAIS(anAIS);
1122     return;
1123   }
1124
1125   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
1126   if (aplane.IsNull()) {
1127 #ifdef OCCT_DEBUG
1128     std::cout << "TPrsStd_ConstraintTools::ComputeConcentric: nul plane" << std::endl;
1129 #endif
1130     NullifyAIS(anAIS);
1131     return;
1132   }
1133   //  Update de l'AIS
1134   Handle(PrsDim_ConcentricRelation) ais;
1135   if (!anAIS.IsNull()) {
1136     ais = Handle(PrsDim_ConcentricRelation)::DownCast(anAIS);
1137     if (ais.IsNull()) {
1138       ais = new PrsDim_ConcentricRelation (shape1,shape2,aplane);
1139     } 
1140     else {
1141       ais->SetFirstShape(shape1);
1142       ais->SetSecondShape(shape2);
1143       ais->SetPlane(aplane);
1144     }
1145   }
1146   else {
1147     ais = new PrsDim_ConcentricRelation (shape1,shape2,aplane);
1148   }
1149
1150   anAIS = ais;
1151 }
1152
1153 //=======================================================================
1154 //function : ComputeRadius
1155 //purpose  : 
1156 //=======================================================================
1157 void TPrsStd_ConstraintTools::ComputeRadius (const Handle(TDataXtd_Constraint)& aConst,
1158                                             Handle(AIS_InteractiveObject)& anAIS) 
1159 {
1160   Standard_Integer nbgeom = aConst->NbGeometries();
1161   if (nbgeom < 1) {
1162 #ifdef OCCT_DEBUG
1163     std::cout << "TPrsStd_ConstraintTools::ComputeRadius: at least one constrainte is needed" << std::endl;    
1164 #endif
1165     NullifyAIS(anAIS);
1166     return;
1167   }
1168
1169   TopoDS_Shape shape1 ;
1170   GetOneShape (aConst,shape1);
1171   if (shape1.IsNull()) {
1172 #ifdef OCCT_DEBUG
1173     std::cout << "TPrsStd_ConstraintTools::ComputeRadius: null shape" << std::endl;
1174 #endif
1175     NullifyAIS(anAIS);
1176     return;
1177   }
1178
1179   // POP on teste si ce n'est pas un compound
1180   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1181       shape1.ShapeType()==TopAbs_COMPSOLID ||
1182       shape1.ShapeType()==TopAbs_SOLID ||
1183       shape1.ShapeType()==TopAbs_SHELL ) {
1184 #ifdef OCCT_DEBUG
1185     std::cout << "TPrsStd_ConstraintTools::ComputeRadius: not good shape" << std::endl;
1186 #endif
1187     NullifyAIS(anAIS);
1188     return;
1189   }
1190       
1191   if (IsFace(shape1))
1192     shape1 = GetFace(shape1);
1193
1194   Standard_Real val1;
1195   TCollection_ExtendedString txt;
1196   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1197
1198   //  Update de l'AIS
1199   Standard_Boolean isplanar(aConst->IsPlanar());
1200   if (isplanar) GetGoodShape(shape1);
1201
1202   Handle(PrsDim_RadiusDimension) ais;
1203   if (!anAIS.IsNull()) {
1204     ais = Handle(PrsDim_RadiusDimension)::DownCast(anAIS);
1205     if (ais.IsNull()) {
1206       ais = new PrsDim_RadiusDimension (shape1);
1207     }
1208     else {
1209       ais->SetMeasuredGeometry(shape1);
1210     }
1211   }
1212   else ais = new PrsDim_RadiusDimension (shape1);
1213
1214   if (isplanar) {
1215     Handle(Geom_Geometry) ageom2;
1216     GetGeom(aConst,ageom2);
1217     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1218     if (aplane.IsNull()) {
1219 #ifdef OCCT_DEBUG
1220       std::cout << "TPrsStd_ConstraintTools::ComputeRadius: nul plane" << std::endl;
1221 #endif
1222       NullifyAIS(anAIS);
1223       return;
1224     }
1225     ais->SetCustomPlane(aplane->Pln());
1226   }
1227   anAIS = ais;
1228 }
1229 // ota -- begin --
1230 //=======================================================================
1231 //function : ComputeMinRadius
1232 //purpose  : 
1233 //=======================================================================
1234 void TPrsStd_ConstraintTools::ComputeMinRadius (const Handle(TDataXtd_Constraint)& aConst,
1235                                                 Handle(AIS_InteractiveObject)& anAIS) 
1236 {
1237   Standard_Integer nbgeom = aConst->NbGeometries();
1238   if (nbgeom < 1) {
1239 #ifdef OCCT_DEBUG
1240     std::cout << "TPrsStd_ConstraintTools::ComputeMinRadius: at least one constrainte is needed" << std::endl;    
1241 #endif
1242     NullifyAIS(anAIS);
1243     return;
1244   }
1245
1246   TopoDS_Shape shape1 ;
1247   GetOneShape (aConst,shape1);
1248   if (shape1.IsNull()) {
1249 #ifdef OCCT_DEBUG
1250     std::cout << "TPrsStd_ConstraintTools::ComputeMinradius: null shape" << std::endl;
1251 #endif
1252     NullifyAIS(anAIS);
1253     return;
1254   }
1255
1256   // POP on teste si ce n'est pas un compound
1257   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1258       shape1.ShapeType()==TopAbs_COMPSOLID ||
1259       shape1.ShapeType()==TopAbs_SOLID ||
1260       shape1.ShapeType()==TopAbs_SHELL ) {
1261 #ifdef OCCT_DEBUG
1262     std::cout << "TPrsStd_ConstraintTools::ComputeMinRadius: not good shape" << std::endl;
1263 #endif
1264     NullifyAIS(anAIS);
1265     return;
1266   }
1267       
1268   if (IsFace(shape1))
1269     shape1 = GetFace(shape1);
1270
1271   Standard_Real val1;
1272   TCollection_ExtendedString txt;
1273   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1274
1275   //  Update de l'AIS
1276   Standard_Boolean isplanar(aConst->IsPlanar());
1277   if (isplanar) GetGoodShape(shape1);
1278
1279   Handle(PrsDim_MinRadiusDimension) ais;
1280   if (!anAIS.IsNull()) {
1281     ais = Handle(PrsDim_MinRadiusDimension)::DownCast(anAIS);
1282     if (ais.IsNull()) {
1283       ais = new PrsDim_MinRadiusDimension (shape1,val1,txt);
1284     }
1285     else {
1286       ais->SetValue(val1);
1287       ais->SetFirstShape(shape1);
1288       ais->SetText(txt);    
1289     }
1290   }
1291   else ais = new PrsDim_MinRadiusDimension (shape1,val1,txt);
1292
1293   if (isplanar) {
1294     Handle(Geom_Geometry) ageom2;
1295     GetGeom(aConst,ageom2);
1296     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1297     if (aplane.IsNull()) {
1298 #ifdef OCCT_DEBUG
1299       std::cout << "TPrsStd_ConstraintTools::ComputeMinRadius: nul plane" << std::endl;
1300 #endif
1301       NullifyAIS(anAIS);
1302       return;
1303     }
1304     ais->SetPlane(aplane);
1305   }
1306   anAIS = ais;
1307 }
1308
1309 //=======================================================================
1310 //function : ComputeMaxRadius
1311 //purpose  : 
1312 //=======================================================================
1313 void TPrsStd_ConstraintTools::ComputeMaxRadius (const Handle(TDataXtd_Constraint)& aConst,
1314                                                 Handle(AIS_InteractiveObject)& anAIS) 
1315 {
1316   Standard_Integer nbgeom = aConst->NbGeometries();
1317   if (nbgeom < 1) {
1318 #ifdef OCCT_DEBUG
1319     std::cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: at least one constrainte is needed" << std::endl;    
1320 #endif
1321     NullifyAIS(anAIS);
1322     return;
1323   }
1324
1325   TopoDS_Shape shape1 ;
1326   GetOneShape (aConst,shape1);
1327   if (shape1.IsNull()) {
1328 #ifdef OCCT_DEBUG
1329     std::cout << "TPrsStd_ConstraintTools::ComputeMaxradius: null shape" << std::endl;
1330 #endif
1331     NullifyAIS(anAIS);
1332     return;
1333   }
1334
1335   // POP on teste si ce n'est pas un compound
1336   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1337       shape1.ShapeType()==TopAbs_COMPSOLID ||
1338       shape1.ShapeType()==TopAbs_SOLID ||
1339       shape1.ShapeType()==TopAbs_SHELL ) {
1340 #ifdef OCCT_DEBUG
1341     std::cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: not good shape" << std::endl;
1342 #endif
1343     NullifyAIS(anAIS);
1344     return;
1345   }
1346
1347   if (IsFace(shape1))
1348     shape1 = GetFace(shape1);
1349
1350   Standard_Real val1;
1351   TCollection_ExtendedString txt;
1352   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1353
1354   //  Update de l'AIS
1355   Standard_Boolean isplanar(aConst->IsPlanar());
1356   if (isplanar) GetGoodShape(shape1);
1357
1358   Handle(PrsDim_MaxRadiusDimension) ais;
1359   if (!anAIS.IsNull()) {
1360     ais = Handle(PrsDim_MaxRadiusDimension)::DownCast(anAIS);
1361     if (ais.IsNull()) {
1362       ais = new PrsDim_MaxRadiusDimension (shape1,val1,txt);
1363     }
1364     else {
1365       ais->SetValue(val1);
1366       ais->SetFirstShape(shape1);
1367       ais->SetText(txt);    
1368     }
1369   }
1370   else ais = new PrsDim_MaxRadiusDimension (shape1,val1,txt);
1371
1372   if (isplanar) {
1373     Handle(Geom_Geometry) ageom2;
1374     GetGeom(aConst,ageom2);
1375     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1376     if (aplane.IsNull()) {
1377 #ifdef OCCT_DEBUG
1378       std::cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: nul plane" << std::endl;
1379 #endif
1380       NullifyAIS(anAIS);
1381       return;
1382     }
1383     ais->SetPlane(aplane);
1384   }
1385   anAIS = ais;
1386 }
1387
1388 //=======================================================================
1389 //function : ComputeEqualDistance
1390 //purpose  : 
1391 //=======================================================================
1392 void TPrsStd_ConstraintTools::ComputeEqualDistance(const Handle(TDataXtd_Constraint)& aConst,
1393                                                    Handle(AIS_InteractiveObject)& anAIS) 
1394 {
1395   Standard_Integer nbgeom = aConst->NbGeometries();
1396   if (nbgeom < 4) {
1397 #ifdef OCCT_DEBUG
1398       std::cout << "TPrsStd_ConstraintTools::ComputeEqual: at least four geometries are needed" << std::endl;
1399 #endif
1400       NullifyAIS(anAIS);
1401       return;
1402     }
1403   TopoDS_Shape aShape1, aShape2, aShape3, aShape4;
1404   Handle(Geom_Geometry) aGeom;
1405   GetShapesAndGeom(aConst, aShape1, aShape2, aShape3, aShape4, aGeom);
1406    if (aShape1.IsNull()||aShape2.IsNull()||
1407        aShape3.IsNull()||aShape4.IsNull()) {
1408 #ifdef OCCT_DEBUG
1409     std::cout << "TPrsStd_ConstraintTools::ComputeEqualDistance : null shape" << std::endl;
1410 #endif
1411     NullifyAIS(anAIS);
1412     return;
1413   }
1414
1415   GetGoodShape(aShape1);
1416   GetGoodShape(aShape2);
1417   GetGoodShape(aShape3);
1418   GetGoodShape(aShape4);
1419   
1420   if (!CheckShapesPair(aShape1, aShape2) || 
1421       !CheckShapesPair(aShape3, aShape4)){
1422 #ifdef OCCT_DEBUG
1423         std::cout << "TPrsStd_ConstraintTools::ComputeEqualDistance : at least one pair of shapes is incorrect"<<std::endl;
1424 #endif
1425         NullifyAIS(anAIS);
1426         return;
1427       }
1428
1429   //Get the plane
1430   Standard_Boolean IsPlanar(aConst->IsPlanar());
1431   Handle(Geom_Plane) aPlane ;
1432   if(IsPlanar) aPlane = Handle(Geom_Plane)::DownCast(aGeom) ; 
1433  
1434   if (!IsPlanar || aPlane.IsNull()) {
1435     //create the plane
1436 #ifdef OCCT_DEBUG
1437     std::cout<< "The constraint plane is not assigned "<< std::endl;
1438 #endif
1439     NullifyAIS(anAIS);
1440     return;
1441   }
1442   
1443   //Update AIS
1444   Handle(PrsDim_EqualDistanceRelation) ais;
1445   if (!anAIS.IsNull()) {
1446     {
1447       ais = Handle(PrsDim_EqualDistanceRelation)::DownCast(anAIS);
1448     
1449       if (ais.IsNull()) 
1450         ais = new PrsDim_EqualDistanceRelation(aShape1, aShape2, aShape3, aShape4, aPlane);
1451       
1452       else {
1453         ais->SetFirstShape(aShape1);
1454         ais->SetSecondShape(aShape2);
1455         ais->SetShape3(aShape3);
1456         ais->SetShape4(aShape4);
1457         ais->SetPlane(aPlane);
1458       }
1459     }
1460   }
1461   else ais = new PrsDim_EqualDistanceRelation(aShape1, aShape2, aShape3, aShape4, aPlane);
1462   
1463   anAIS = ais;  
1464
1465   return;
1466 }
1467
1468 //======================================================================
1469 // function : CheckShapesPair
1470 // purpose  : checks the types of two shapes. 
1471 //            If the types aShape1 and aShape2 are EDGE - EDGE,
1472 //                                              or EDGE - VERTEX,
1473 //                                              or VERTEX - VERTEX,
1474 //                                              or CIRCLE - CIRCLE,
1475 //                                              or CIRCLE - VERTEX,
1476 //            then function returns TRUE, otherwise FALSE.
1477 //======================================================================
1478 static Standard_Boolean CheckShapesPair(const TopoDS_Shape& aShape1, 
1479                                     const TopoDS_Shape& aShape2)
1480 {
1481   //Check whether the shapes form a correct pair.
1482   if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_EDGE)
1483     {
1484       BRepAdaptor_Curve aCurve1(TopoDS::Edge(aShape1));
1485       BRepAdaptor_Curve aCurve2(TopoDS::Edge(aShape2));
1486       if (aCurve1.GetType() == GeomAbs_Line && aCurve2.GetType() == GeomAbs_Line)
1487         { //Are lines parallel ?
1488           gp_Dir aDir1 = aCurve1.Line().Direction();
1489           gp_Dir aDir2 = aCurve2.Line().Direction();
1490           if (!(aDir1.IsParallel(aDir2, Precision::Confusion()))) {
1491 #ifdef OCCT_DEBUG
1492             std::cout << " Lines are not parallel"<<std::endl;
1493 #endif
1494             return Standard_False;
1495           }
1496         }
1497       else if (aCurve1.GetType() == GeomAbs_Circle && aCurve2.GetType() == GeomAbs_Circle)
1498         {
1499           gp_Pnt aCntr1 = aCurve1.Circle().Location(); //get the circle center
1500           gp_Pnt aCntr2 = aCurve2.Circle().Location(); //get the circle center
1501           if (!aCntr1.IsEqual(aCntr2,Precision::Confusion())){
1502 #ifdef OCCT_DEBUG
1503             std::cout << " Circles are not concentric"<<std::endl;
1504 #endif
1505             return Standard_False;
1506           }
1507         }
1508       else {
1509 #ifdef OCCT_DEBUG
1510         std::cout << "Incorrect pair of curves "<<std::endl;
1511 #endif
1512         return Standard_False;
1513       }
1514     }
1515   else if ( aShape1.ShapeType() != TopAbs_VERTEX || aShape2.ShapeType() != TopAbs_VERTEX)
1516     {
1517       gp_Pnt aPnt;
1518       BRepAdaptor_Curve aCurve;
1519       if ( aShape1.ShapeType() == TopAbs_VERTEX) {
1520         aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
1521         aCurve.Initialize(TopoDS::Edge(aShape2));
1522       }
1523       else {
1524         aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
1525         aCurve.Initialize(TopoDS::Edge(aShape1));
1526       }
1527       if ( aCurve.GetType() == GeomAbs_Circle)
1528         {
1529           gp_Pnt aCntr = aCurve.Circle().Location();
1530           if (!aCntr.IsEqual(aPnt, Precision::Confusion())){
1531 #ifdef OCCT_DEBUG
1532             std::cout << " The point doesn't coincide with the circle center"<<std::endl;
1533 #endif
1534             return Standard_False;
1535           }
1536         }
1537     }
1538   return Standard_True;
1539 }
1540
1541 //=======================================================================
1542 //function : ComputeEqualRadius
1543 //purpose  : 
1544 //=======================================================================
1545 void TPrsStd_ConstraintTools::ComputeEqualRadius(const Handle(TDataXtd_Constraint)& aConst,
1546                                                  Handle(AIS_InteractiveObject)& anAIS) 
1547 {
1548   Standard_Integer nbgeom = aConst->NbGeometries();
1549   if (nbgeom < 2) {
1550 #ifdef OCCT_DEBUG
1551     std::cout << "TPrsStd_ConstraintTools::ComputeEqualRadius: at least two geometries are needed" << std::endl;
1552 #endif
1553     NullifyAIS(anAIS);
1554     return;
1555   }
1556   TopoDS_Shape shape1, shape2;
1557   Handle(Geom_Geometry) ageom3;
1558   
1559   GetShapesAndGeom(aConst, shape1, shape2, ageom3);
1560   if (shape1.IsNull()||shape2.IsNull()) {
1561 #ifdef OCCT_DEBUG
1562     std::cout << "TPrsStd_ConstraintTools::ComputeEqualRadius : null shape" << std::endl;
1563 #endif
1564     NullifyAIS(anAIS);
1565     return;
1566   }
1567   
1568   //  Update AIS
1569   Standard_Boolean IsPlanar(aConst->IsPlanar());
1570  
1571   GetGoodShape(shape1);
1572   GetGoodShape(shape2);
1573   const TopoDS_Edge edge1 = TopoDS::Edge(shape1);
1574   const TopoDS_Edge edge2 = TopoDS::Edge(shape2);
1575   Handle(Geom_Plane) aplane ;
1576   
1577   if (IsPlanar) aplane = Handle(Geom_Plane)::DownCast(ageom3) ;
1578   
1579   if (!IsPlanar || aplane.IsNull()) {
1580     // check are the planes of edge1 and edge2 coincident
1581     BRepAdaptor_Curve aCurve( edge1 );
1582     Handle( Geom_Curve ) aProjCurve = aCurve.Curve().Curve();
1583     gp_Circ aCircle = (Handle( Geom_Circle )::DownCast( aProjCurve ))->Circ();
1584     gp_Ax3 anAx31(aCircle.Position()); //get the circle axis
1585     // get the circle plane 
1586     Handle(Geom_Plane) aPlane1 = new Geom_Plane (anAx31);
1587
1588     aCurve.Initialize(edge2);
1589     aProjCurve = aCurve.Curve().Curve();
1590     aCircle = (Handle( Geom_Circle )::DownCast( aProjCurve ))->Circ();
1591     gp_Ax3 anAx32(aCircle.Position()); //get the circle axis
1592     // get the circle plane 
1593     Handle(Geom_Plane) aPlane2 = new Geom_Plane (anAx32);
1594
1595     Standard_Real A, B, C ,D1, D2;
1596     aPlane1->Coefficients(A, B, C, D1);//Get normalized coefficients
1597     aPlane2->Coefficients(A, B, C, D2);//Get normalized coefficients
1598     const gp_Dir& aDir1 = anAx31.Direction();
1599     const gp_Dir& aDir2 = anAx32.Direction();
1600     
1601     if(Abs(D1 - D2) < Precision::Confusion() &&
1602        aDir1.IsParallel(aDir2, Precision::Confusion()))
1603       aplane = aPlane2;
1604     else {
1605 #ifdef OCCT_DEBUG
1606       std::cout << "TPrsStd_ConstraintTools::ComputeRadiusRelation: nul plane" << std::endl;
1607 #endif
1608       NullifyAIS(anAIS);
1609       return;
1610     }
1611   }   
1612   Handle(PrsDim_EqualRadiusRelation) ais;
1613   if (!anAIS.IsNull()) {
1614     ais = Handle(PrsDim_EqualRadiusRelation)::DownCast(anAIS);
1615     
1616     if (ais.IsNull()) {
1617       ais = new PrsDim_EqualRadiusRelation(edge1, edge2, aplane);
1618       }
1619     else {
1620       ais->SetFirstShape(shape1);
1621       ais->SetSecondShape(shape2);
1622       ais->SetPlane(aplane);
1623     }
1624   }
1625   else {
1626     ais = new PrsDim_EqualRadiusRelation(edge1, edge2, aplane);
1627   }
1628   
1629   anAIS = ais;
1630 }
1631 //ota -- end --
1632
1633 //=======================================================================
1634 //function : ComputeDiameter
1635 //purpose  : 
1636 //=======================================================================
1637 void TPrsStd_ConstraintTools::ComputeDiameter(const Handle(TDataXtd_Constraint)& aConst,
1638                                              Handle(AIS_InteractiveObject)& anAIS) 
1639 {
1640   Standard_Integer nbgeom = aConst->NbGeometries();
1641   if (nbgeom < 1) {
1642 #ifdef OCCT_DEBUG
1643     std::cout << "TPrsStd_ConstraintTools::ComputeDiameter: at least one constrainte is needed" << std::endl;
1644 #endif
1645     NullifyAIS(anAIS);
1646     return;
1647   }
1648   TopoDS_Shape shape1 ;
1649   
1650   GetOneShape(aConst,shape1);
1651   if (shape1.IsNull()) {
1652 #ifdef OCCT_DEBUG
1653     std::cout << "TPrsStd_ConstraintTools::ComputeDiameter : null shape" << std::endl;
1654 #endif
1655     NullifyAIS(anAIS);
1656     return;
1657   }
1658   Standard_Real val1;
1659   TCollection_ExtendedString txt;
1660   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1661
1662   //  Update de l'AIS
1663   Standard_Boolean IsPlanar(aConst->IsPlanar());
1664   if (IsPlanar) GetGoodShape(shape1);
1665   Handle(PrsDim_DiameterDimension) ais;
1666   if (!anAIS.IsNull()) {
1667     ais = Handle(PrsDim_DiameterDimension)::DownCast(anAIS);
1668     if (ais.IsNull()) {
1669       ais = new PrsDim_DiameterDimension (shape1);
1670     }
1671     else {
1672       ais->SetMeasuredGeometry(shape1);
1673     }
1674   }
1675   else ais = new PrsDim_DiameterDimension (shape1);
1676
1677   if (IsPlanar) {
1678     Handle(Geom_Geometry) ageom2;
1679     GetGeom(aConst,ageom2);
1680     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1681     if (aplane.IsNull()) {
1682 #ifdef OCCT_DEBUG
1683       std::cout << "TPrsStd_ConstraintTools::ComputeDiameter: nul plane" << std::endl;
1684 #endif
1685       NullifyAIS(anAIS);
1686       return;
1687     }
1688     //ais->SetCustomPlane(aplane);
1689   }
1690   anAIS = ais;
1691 }
1692
1693
1694 //=======================================================================
1695 //function : ComputeFix
1696 //purpose  : 
1697 //=======================================================================
1698 void TPrsStd_ConstraintTools::ComputeFix(const Handle(TDataXtd_Constraint)& aConst,
1699                                         Handle(AIS_InteractiveObject)& anAIS) 
1700 {
1701   Standard_Integer nbgeom = aConst->NbGeometries();
1702   if (nbgeom < 1) {
1703 #ifdef OCCT_DEBUG
1704     std::cout << "TPrsStd_ConstraintTools::ComputeFix: at least one constrainte is needed" << std::endl;
1705 #endif
1706     NullifyAIS(anAIS);
1707     return;
1708   }
1709   if (!aConst->IsPlanar()) {
1710 #ifdef OCCT_DEBUG
1711     std::cout << "TPrsStd_ConstraintTools::ComputeFix: must be a planar constraint" << std::endl;
1712 #endif
1713     NullifyAIS(anAIS);
1714     return;
1715   }
1716
1717   TopoDS_Shape shape1 ;
1718   Handle(Geom_Geometry) ageom2;
1719   
1720   GetOneShape(aConst,shape1);
1721   if (shape1.IsNull()) {
1722 #ifdef OCCT_DEBUG
1723     std::cout << "TPrsStd_ConstraintTools::ComputeFix : null shape" << std::endl;
1724 #endif
1725     NullifyAIS(anAIS);
1726     return;
1727   }  
1728   GetGoodShape(shape1);
1729   GetGeom(aConst,ageom2);
1730   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1731   if (aplane.IsNull()) {
1732 #ifdef OCCT_DEBUG
1733     std::cout << "TPrsStd_ConstraintTools::ComputeFix: nul plane" << std::endl;
1734 #endif
1735     NullifyAIS(anAIS);
1736     return;
1737   }
1738   //  Update de l'AIS
1739   Handle(PrsDim_FixRelation) ais;
1740   if (!anAIS.IsNull()) {
1741     ais = Handle(PrsDim_FixRelation)::DownCast(anAIS);
1742     if (ais.IsNull()) {
1743       ais = new PrsDim_FixRelation (shape1,aplane);
1744     }
1745     else {
1746       ais->SetFirstShape(shape1);
1747       ais->SetPlane(aplane);
1748     }
1749   }
1750   else ais = new PrsDim_FixRelation (shape1,aplane);
1751
1752   anAIS = ais;
1753 }
1754
1755 //=======================================================================
1756 //function : ComputeOffset
1757 //purpose  : 
1758 //=======================================================================
1759 void TPrsStd_ConstraintTools::ComputeOffset (const Handle(TDataXtd_Constraint)& aConst,
1760                                             Handle(AIS_InteractiveObject)& anAIS) 
1761 {
1762   // Get plane for planar constraint
1763   Standard_Boolean is_planar (aConst->IsPlanar());
1764   Handle(Geom_Plane) aplane;      
1765   if (is_planar) {
1766     Handle(Geom_Geometry) ageom;
1767     GetGeom (aConst,ageom);
1768     aplane = Handle(Geom_Plane)::DownCast (ageom);
1769     if (aplane.IsNull()) {
1770 #ifdef OCCT_DEBUG
1771       std::cout << "TPrsStd_ConstraintTools::ComputeOffset: null plane" << std::endl;
1772 #endif
1773       NullifyAIS(anAIS);
1774       return;
1775     }
1776   }
1777
1778   // Get shapes
1779   TopoDS_Shape S1, S2;
1780   Standard_Integer nbgeom = aConst->NbGeometries();
1781   if (nbgeom == 1) {
1782     Handle(TNaming_NamedShape) ageom1 = aConst->GetGeometry(1);
1783     // c'est une shape qui contient les faces generees par les faces d'origines
1784     TNaming_Iterator It (ageom1);
1785     if (It.More()) {
1786       S1 = It.OldShape();
1787       S2 = It.NewShape();
1788     }
1789   }
1790   else
1791   if (nbgeom == 2)  {
1792     // Get geometry of the constraint
1793     GetTwoShapes (aConst,S1,S2);
1794   }
1795
1796   if (S1.IsNull() || S2.IsNull()) {
1797 #ifdef OCCT_DEBUG
1798     std::cout << "TPrsStd_ConstraintTools::ComputeOffset: null shape" << std::endl;
1799 #endif
1800     NullifyAIS(anAIS);
1801     return;
1802   }
1803
1804
1805   Standard_Real val1;
1806   TCollection_ExtendedString txt;
1807   Handle(PrsDim_LengthDimension) ais;
1808   //Handle(Prs3d_Drawer) aDrawer;
1809
1810   if (nbgeom == 1)
1811   {
1812     ComputeTextAndValue (aConst,val1,txt,Standard_False);
1813     if (!anAIS.IsNull())
1814     {
1815       ais = Handle(PrsDim_LengthDimension)::DownCast(anAIS);
1816     }
1817
1818     if (S1.ShapeType() == TopAbs_FACE && S2.ShapeType() == TopAbs_FACE)
1819     {
1820       if (ais.IsNull())
1821       {
1822         ais = new PrsDim_LengthDimension (TopoDS::Face(S1),TopoDS::Face(S2));
1823       }
1824       else
1825       {
1826         ais->SetMeasuredShapes (S1, S2);
1827         ais->SetCustomValue(val1);
1828       }
1829
1830       if (is_planar)
1831       {
1832         ais->SetCustomPlane (aplane->Pln());
1833       }
1834
1835       anAIS = ais;
1836       return;
1837     }
1838     else
1839     if (S1.ShapeType() == TopAbs_EDGE && S2.ShapeType() == TopAbs_EDGE) {
1840       // Find a plane for the dimension
1841       TopoDS_Edge OE = TopoDS::Edge(S1);
1842       BRepAdaptor_Curve CURVE(OE);
1843       if (CURVE.GetType() == GeomAbs_Line)  {
1844         // Works only with line !!
1845         Handle(Geom_Geometry) aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1846         gp_Lin OLin = Handle(Geom_Line)::DownCast (aGeomGeometry)->Lin();
1847         TopoDS_Edge NE = TopoDS::Edge(S2);
1848         CURVE.Initialize (NE);
1849         aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1850         gp_Lin NLin = Handle(Geom_Line)::DownCast (aGeomGeometry)->Lin();
1851         gp_Dir TDir (NLin.Location().XYZ() - OLin.Location().XYZ());
1852         aplane = new Geom_Plane (NLin.Location(),NLin.Direction()^TDir);
1853
1854         if (ais.IsNull()) {
1855           ais = new PrsDim_LengthDimension (S1,S2,aplane->Pln());
1856         }
1857         else {
1858           ais->SetMeasuredShapes (S1, S2);
1859           ais->SetCustomValue(val1);
1860
1861           ais->SetCustomPlane (aplane->Pln());
1862         }
1863         anAIS = ais;
1864         return;
1865       }
1866       else
1867       if (CURVE.GetType() == GeomAbs_Circle)  {
1868         Handle(Geom_Geometry) aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1869         gp_Ax1 ax = Handle(Geom_Circle)::DownCast (aGeomGeometry)->Circ().Axis();
1870         aplane = new Geom_Plane (ax.Location(),ax.Direction());
1871         is_planar = Standard_True;
1872       }
1873     }
1874   }
1875
1876
1877   if (!is_planar)  {
1878     if (S1.ShapeType() == TopAbs_COMPOUND && 
1879         S2.ShapeType() == TopAbs_COMPOUND)  {
1880       // Resultat d'un offset - on reconstruit un wire pour determiner un plan
1881       TopoDS_Wire w1;
1882       BRep_Builder B;
1883       B.MakeWire (w1);
1884       TopExp_Explorer exp (S1,TopAbs_EDGE);
1885       for (;exp.More();exp.Next())
1886         B.Add (w1,exp.Current());
1887
1888       BRepBuilderAPI_MakeFace MkF (w1,Standard_True);
1889       if (MkF.IsDone())  {
1890         Handle(Geom_Surface) aGeomSurface = BRep_Tool::Surface(MkF.Face());
1891         aplane = Handle(Geom_Plane)::DownCast (aGeomSurface);
1892         is_planar = Standard_True;
1893       }
1894     }
1895   }
1896
1897   if (is_planar) {
1898     ComputeTextAndValue (aConst,val1,txt,Standard_False);
1899     TopExp_Explorer EXP1 (S1,TopAbs_VERTEX);
1900     S1 = EXP1.Current();
1901     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(S1));
1902       
1903     TopoDS_Vertex nearest;
1904     Standard_Real dist(RealLast());
1905
1906     for (TopExp_Explorer EXP2(S2,TopAbs_VERTEX); EXP2.More(); EXP2.Next()) {
1907       const TopoDS_Vertex& current = TopoDS::Vertex(EXP2.Current());
1908       gp_Pnt curpnt = BRep_Tool::Pnt(current);
1909       Standard_Real curdist = P.SquareDistance(curpnt);
1910       if (curdist < dist) {
1911         nearest= current;
1912         dist = curdist;
1913       }
1914     }
1915     S2 = nearest;
1916     ais = Handle(PrsDim_LengthDimension)::DownCast(anAIS);
1917     if (ais.IsNull()) {
1918       ais = new PrsDim_LengthDimension (S1,S2,aplane->Pln());
1919     }
1920     else {
1921       ais->SetMeasuredShapes (S1, S2);
1922       ais->SetCustomValue (val1);
1923       ais->SetCustomPlane (aplane->Pln ());
1924     }
1925     anAIS = ais;
1926     return;
1927   }
1928
1929 #ifdef OCCT_DEBUG
1930   std::cout << "TPrsStd_ConstraintTools::ComputeOffset: Case not implemented" << std::endl;
1931 #endif
1932   NullifyAIS(anAIS);
1933 }
1934
1935
1936 //=======================================================================
1937 //function : ComputePlacement
1938 //purpose  : 
1939 //=======================================================================
1940 void TPrsStd_ConstraintTools::ComputePlacement
1941 (const Handle(TDataXtd_Constraint)& aConst,
1942  Handle(AIS_InteractiveObject)& anAIS) 
1943 {
1944   Standard_Integer nbgeom = aConst->NbGeometries();
1945   if (nbgeom < 2) 
1946     throw Standard_ProgramError("TPrsStd_ConstraintTools::ComputePlacement: at leat two constraints are needed");
1947   
1948   TopoDS_Shape shape1,shape2 ;
1949   GetTwoShapes(aConst,shape1,shape2);
1950   if (shape1.IsNull() || shape2.IsNull()) {
1951 #ifdef OCCT_DEBUG
1952     std::cout << "TPrsStd_ConstraintTools::ComputePlacement: nul shape" << std::endl;
1953 #endif
1954     NullifyAIS(anAIS);
1955     return;
1956   }
1957   
1958   Standard_Real val1=0.0;
1959   TCollection_ExtendedString txt= " ";
1960   if (aConst->IsDimension()) {
1961     ComputeTextAndValue(aConst,val1,txt,Standard_False);
1962   }
1963   //  Update de l'AIS
1964   Handle(PrsDim_OffsetDimension) ais;
1965   if (anAIS.IsNull()) {
1966     ais = new PrsDim_OffsetDimension(GetFace(shape1),GetFace(shape2),val1,txt);
1967     ais->SetArrowSize(val1/20.);
1968   } else {
1969     ais = Handle(PrsDim_OffsetDimension)::DownCast(anAIS);
1970     if (ais.IsNull()) {
1971       ais = new PrsDim_OffsetDimension(GetFace(shape1),GetFace(shape2),val1,txt);
1972       ais->SetArrowSize(val1/20.);
1973     } else {
1974       ais->SetFirstShape(GetFace(shape1));
1975       ais->SetSecondShape(GetFace(shape2));
1976       ais->SetValue(val1);
1977       ais->SetText(txt);
1978       ais->SetArrowSize(val1/20.);
1979     }
1980   }
1981   if (GetFace(shape1).IsNull() || GetFace(shape2).IsNull()) ais.Nullify();
1982   anAIS = ais;
1983 }
1984
1985 //=======================================================================
1986 //function : ComputeOthers
1987 //purpose  : 
1988 //=======================================================================
1989 void TPrsStd_ConstraintTools::ComputeOthers
1990 (const Handle(TDataXtd_Constraint)& /*aConst*/,
1991  Handle(AIS_InteractiveObject)& /*anAIS*/) 
1992 {
1993 }
1994
1995 //=======================================================================
1996 //function : GetOneShape
1997 //purpose  : 
1998 //=======================================================================
1999 void TPrsStd_ConstraintTools::GetOneShape
2000 (const Handle(TDataXtd_Constraint)& aConst,
2001  TopoDS_Shape& aShape) 
2002 {
2003   const Handle(TNaming_NamedShape)& ageom1 = aConst->GetGeometry(1);
2004   if (!ageom1.IsNull()) aShape =  TNaming_Tool::CurrentShape(ageom1);
2005 }
2006
2007 //=======================================================================
2008 //function : GetTwoShapes
2009 //purpose  : 
2010 //=======================================================================
2011 void TPrsStd_ConstraintTools::GetTwoShapes
2012 (const Handle(TDataXtd_Constraint)& aConst,
2013  TopoDS_Shape& aShape1,
2014  TopoDS_Shape& aShape2) 
2015 {
2016   const Handle(TNaming_NamedShape)& ageom1 = aConst->GetGeometry(1);    
2017   if (!ageom1.IsNull()) aShape1 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(1));
2018   const Handle(TNaming_NamedShape)& ageom2 = aConst->GetGeometry(2);    
2019   if (!ageom2.IsNull()) aShape2 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(2));
2020 }
2021
2022 //=======================================================================
2023 //function : GetShapesAndGeom
2024 //purpose  : 
2025 //=======================================================================
2026 void TPrsStd_ConstraintTools::GetShapesAndGeom
2027 (const Handle(TDataXtd_Constraint)& aConst,
2028  TopoDS_Shape& aShape1,
2029  TopoDS_Shape& aShape2,
2030  Handle(Geom_Geometry)& aGeom) 
2031 {
2032   GetTwoShapes(aConst,aShape1,aShape2);
2033   GetGeom(aConst,aGeom);
2034 }
2035
2036 //=======================================================================
2037 //function : GetShapesAndGeom
2038 //purpose  : 
2039 //=======================================================================
2040 void TPrsStd_ConstraintTools::GetShapesAndGeom
2041 (const Handle(TDataXtd_Constraint)& aConst,
2042  TopoDS_Shape& aShape1,
2043  TopoDS_Shape& aShape2,
2044  TopoDS_Shape& aShape3,
2045  Handle(Geom_Geometry)& aGeom) 
2046 {
2047   GetTwoShapes(aConst,aShape1,aShape2);
2048   const Handle(TNaming_NamedShape)& ageom3 = aConst->GetGeometry(3);//ota: GetGeometry(2) was  
2049   if (!ageom3.IsNull()) aShape3 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(3));
2050   GetGeom(aConst,aGeom);
2051 }
2052
2053 //=======================================================================
2054 //function : GetShapesAndGeom
2055 //purpose  : 
2056 //=======================================================================
2057 void TPrsStd_ConstraintTools::GetShapesAndGeom
2058   (const Handle(TDataXtd_Constraint)& aConst,
2059    TopoDS_Shape& aShape1,
2060    TopoDS_Shape& aShape2,
2061    TopoDS_Shape& aShape3,
2062    TopoDS_Shape& aShape4,
2063    Handle(Geom_Geometry)& aGeom) 
2064 {
2065   GetTwoShapes(aConst,aShape1, aShape2 );
2066   const Handle(TNaming_NamedShape)& ageom3 = aConst->GetGeometry(3);    
2067   if (!ageom3.IsNull()) aShape3 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(3));
2068   const Handle(TNaming_NamedShape)& ageom4 = aConst->GetGeometry(4); 
2069   if (!ageom4.IsNull()) aShape4 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(4));
2070   GetGeom(aConst,aGeom);
2071 }
2072
2073 //=======================================================================
2074 //function : ComputeCoincident
2075 //purpose  : 
2076 //=======================================================================
2077 void TPrsStd_ConstraintTools::ComputeCoincident(const Handle(TDataXtd_Constraint)& aConst,
2078                                                Handle(AIS_InteractiveObject)& anAIS) 
2079 {
2080   Standard_Integer nbgeom = aConst->NbGeometries();
2081   if (nbgeom < 2) {
2082 #ifdef OCCT_DEBUG
2083     std::cout << "TPrsStd_ConstraintTools::ComputeCoincident: at leat two constraintes are needed" << std::endl;
2084 #endif
2085     NullifyAIS(anAIS);
2086     return; 
2087   }
2088   
2089   if (!aConst->IsPlanar()) { 
2090 #ifdef OCCT_DEBUG
2091     std::cout << "TPrsStd_ConstraintTools::ComputeCoincident: must be a planar constraint" << std::endl;
2092 #endif
2093     anAIS.Nullify() ; 
2094     return;
2095   }
2096   
2097   TopoDS_Shape shape1,shape2 ;
2098   Handle(Geom_Geometry) ageom;
2099   GetShapesAndGeom(aConst,shape1,shape2,ageom);
2100   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast (ageom);
2101   if (shape1.IsNull() || shape2.IsNull()) {
2102 #ifdef OCCT_DEBUG
2103     std::cout << "TPrsStd_ConstraintTools::ComputeCoincident: nul shape" << std::endl;
2104 #endif
2105     NullifyAIS(anAIS);
2106     return;
2107   }
2108
2109   GetGoodShape(shape1);
2110   GetGoodShape(shape2);
2111   if (aplane.IsNull()) {
2112 #ifdef OCCT_DEBUG
2113     std::cout << "TPrsStd_ConstraintTools::ComputeCoincident: nul plane" << std::endl;
2114 #endif
2115     NullifyAIS(anAIS);
2116     return;
2117   }
2118   
2119   //  Update de l'AIS
2120   Handle(PrsDim_IdenticRelation) ais;
2121   if (anAIS.IsNull()) ais = new PrsDim_IdenticRelation(shape1,shape2,aplane);
2122   else {
2123     ais = Handle(PrsDim_IdenticRelation)::DownCast(anAIS);
2124     if (ais.IsNull()) {
2125       ais = new PrsDim_IdenticRelation(shape1,shape2,aplane);
2126     }
2127     else {
2128       ais->SetFirstShape(shape1);
2129       ais->SetSecondShape(shape2);
2130       ais->SetPlane(aplane);
2131     }
2132   }
2133   anAIS = ais;
2134 }
2135
2136 //=======================================================================
2137 //function : ComputeRound
2138 //purpose  : 
2139 //=======================================================================
2140 void TPrsStd_ConstraintTools::ComputeRound(const Handle(TDataXtd_Constraint)& aConst,
2141                                                Handle(AIS_InteractiveObject)& anAIS) 
2142 {
2143   Standard_Integer nbgeom = aConst->NbGeometries();
2144   if (nbgeom < 1) {
2145 #ifdef OCCT_DEBUG
2146     std::cout << "TPrsStd_ConstraintTools::ComputeRound: at leat one geometry is needed" << std::endl;
2147 #endif
2148     NullifyAIS(anAIS);
2149     return; 
2150   }
2151   TopoDS_Shape shape1;
2152   GetOneShape (aConst,shape1);
2153   if (shape1.IsNull()) {
2154 #ifdef OCCT_DEBUG
2155     std::cout << "TPrsStd_ConstraintTools::ComputePlacement: nul shape" << std::endl;
2156 #endif
2157     NullifyAIS(anAIS);
2158     return;
2159   }
2160   
2161   Standard_Real val1;
2162   TCollection_ExtendedString txt;
2163   ComputeTextAndValue(aConst,val1,txt,Standard_False);
2164   
2165   //  Update de l'AIS
2166   Handle(PrsDim_RadiusDimension) ais;
2167
2168   {
2169    try {
2170      OCC_CATCH_SIGNALS
2171      if (anAIS.IsNull()) ais = 
2172        new PrsDim_RadiusDimension(shape1);
2173      else {
2174        ais = Handle(PrsDim_RadiusDimension)::DownCast(anAIS);
2175        if (ais.IsNull()) {
2176          ais = new PrsDim_RadiusDimension(shape1);
2177        }
2178        else {
2179          ais->SetMeasuredGeometry(shape1);
2180        }
2181      }
2182    }
2183    catch(Standard_Failure const&) {
2184      ais.Nullify();
2185    }
2186  }
2187   anAIS = ais;
2188 }
2189
2190 //=======================================================================
2191 //function : GetGeom
2192 //purpose  : 
2193 //=======================================================================
2194 void TPrsStd_ConstraintTools::GetGeom(const Handle(TDataXtd_Constraint)& aConst,
2195                                      Handle(Geom_Geometry)& aGeom)
2196 {  
2197   Handle(TNaming_NamedShape) atgeom = aConst->GetPlane();
2198   if (atgeom.IsNull()) {
2199 #ifdef OCCT_DEBUG
2200     std::cout<<"TPrsStd_ConstraintTools::GetGeom : aConst->GetPlane().IsNull()"<<std::endl;
2201 #endif
2202     return;
2203   }
2204   gp_Pln aplane;
2205   gp_Lin anaxis;
2206   gp_Pnt apoint;
2207   
2208   TDF_Label label = atgeom->Label();
2209
2210   Handle(TNaming_NamedShape) NS;
2211   if(label.FindAttribute(TNaming_NamedShape::GetID(),NS)){
2212     TopoDS_Shape s = TNaming_Tool::GetShape(NS);
2213     if(s.IsNull()) return;
2214   }
2215
2216   if (TDataXtd_Geometry::Plane(label,aplane)) aGeom =  new Geom_Plane(aplane);
2217   else if (TDataXtd_Geometry::Line(label,anaxis)) aGeom =  new Geom_Line(anaxis);
2218   else if (TDataXtd_Geometry::Point(label,apoint)) aGeom =  new Geom_CartesianPoint(apoint);
2219 #ifdef OCCT_DEBUG
2220   else {
2221     std::cout << "TPrsStd_ConstraintTools::GetGeom no geom on label " << std::endl;
2222   }
2223 #endif  
2224 }
2225