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