diff --git a/doc/salome/gui/GEOM/images/add_dimension.png b/doc/salome/gui/GEOM/images/add_dimension.png
new file mode 100644
index 000000000..a632eba82
Binary files /dev/null and b/doc/salome/gui/GEOM/images/add_dimension.png differ
diff --git a/doc/salome/gui/GEOM/images/dialog.png b/doc/salome/gui/GEOM/images/dialog.png
index 09459032f..c46b6b571 100755
Binary files a/doc/salome/gui/GEOM/images/dialog.png and b/doc/salome/gui/GEOM/images/dialog.png differ
diff --git a/doc/salome/gui/GEOM/images/dimensions_preview.png b/doc/salome/gui/GEOM/images/dimensions_preview.png
new file mode 100644
index 000000000..004a05014
Binary files /dev/null and b/doc/salome/gui/GEOM/images/dimensions_preview.png differ
diff --git a/doc/salome/gui/GEOM/images/pref15.png b/doc/salome/gui/GEOM/images/pref15.png
index 82189e99d..c4b2cac4d 100755
Binary files a/doc/salome/gui/GEOM/images/pref15.png and b/doc/salome/gui/GEOM/images/pref15.png differ
diff --git a/doc/salome/gui/GEOM/input/add_dimension.doc b/doc/salome/gui/GEOM/input/add_dimension.doc
new file mode 100644
index 000000000..691132280
--- /dev/null
+++ b/doc/salome/gui/GEOM/input/add_dimension.doc
@@ -0,0 +1,44 @@
+/*!
+
+\page add_dimension_page Add Dimension
+
+\image html add_dimension.png
+
+The dialog is opened from \ref managing_dimensions_page "Manage Dimensions" dialog when "Add" button is clicked.
+This dialog allows creating measurement dimension for the selected geometrical object.
+The following types of dimensions can be constructed:
+
+Length.
+Diameter.
+Angle.
+
+
+Being constructed, the dimension is positioned by application such that the user is able to see it from the most appropriate angle of view.
+The application selects one of the best matching planes allowed for the dimension. If extending the dimension by increasing length of flyouts
+make sense, then the application extends the flyouts for a default value specified on the \ref geometry_preferences_page "geometry preference dialog".
+
+Once constructed, the geometrical properties of dimension preview (flyout, plane) become interactively editable in OCC viewer.
+For the description of interactive operations please refer to corresponding section at \ref managing_dimensions_page "Manage Dimensions" page.
+
+The legnth dimension can be constructed in three ways: as length on edge, as length between two points and as length between two parallel lines.
+In order to construct the dimension, the selected geometry should met the following conditions:
+
+Edge length - only the line edges are accepted. E.g. constructed from line segment, on two points.
+Two points - any two points.
+Parallel edges - only the parallel line edges are accepted.
+
+
+The diameter dimension can be constructed for the following geometry types:
+
+Arc and circle. The selected geometry should be an arc, a circular edge or a circular face.
+Sphere, cylinder, cone, torus.
+
+
+The angle dimension can be constructed in two ways: as angle between two edges, as angle by three points.
+The following conditions should be met:
+
+Two edges. The edges should be located in same plane.
+ Three points. Any three points, with the second point being the center of the angle.
+
+
+*/
diff --git a/doc/salome/gui/GEOM/input/geometry_preferences.doc b/doc/salome/gui/GEOM/input/geometry_preferences.doc
index bfce50129..6ad3270cb 100644
--- a/doc/salome/gui/GEOM/input/geometry_preferences.doc
+++ b/doc/salome/gui/GEOM/input/geometry_preferences.doc
@@ -49,6 +49,20 @@ predefined materials.
+
+Dimensions (Measurements)
+
+Color - allows to define color for persistent dimension presentations.
+Line width - allows to define pixel width of dimension lines.
+Font height - allows to define height of dimension text.
+Length of arrows - allows to define length of dimension arrows.
+Length measurement units - allows to define units of measurement for lengths dimensions.
+Angle measurement units - allows to define units of measurement for angles dimensions.
+Show units of measurements - when this option is on, the measurement units are added as prefix to value label of dimension.
+Default flyout length - allows to define default flyout length used when creating the dimensions. The length can be interactively changed after creation by moving the flyouts.
+
+
+
Number of isolines - allows to specify the number of isolines along Along U and Along V coordinate axes. They are shown on each selected face. For example:
diff --git a/doc/salome/gui/GEOM/input/managing_dimensions.doc b/doc/salome/gui/GEOM/input/managing_dimensions.doc
new file mode 100644
index 000000000..83c1df9fb
--- /dev/null
+++ b/doc/salome/gui/GEOM/input/managing_dimensions.doc
@@ -0,0 +1,64 @@
+/*!
+
+\page managing_dimensions_page Manage Dimensions
+
+\image html dimensions_preview.png
+
+Dimensions of sub-elements can be measured for a geometrical object representing a shape.
+There are three types of dimensions available
+
+Length.
+Diameter.
+Angle.
+
+
+Measurement units and group of presentation attributes for the measurement dimensions can be seen and changed from the \ref geometry_preferences_page "geometry preference dialog".
+
+The application entities, representing the dimensions, are associated with the geometrical object for which its elements are measured. The dimensions follow their associated object on show/hide, transformation and deletion operations.
+
+Each dimension instance has its local visibility flag intended for showing/hiding it among other dimensions of the associated object.
+
+\image html manage_dimensions.png
+
+This dialog allows managing list of dimensions for the selected geometrical object.
+It shows the list and provides dimension creation and removal, modification of name and visibility, along with the interactive modification of dimension's geometrical properties.
+
+The list view groups dimension objects by their type: "Distances", "Diameters", "Angles". This view allows selection of the dimensions and lets user to change the dimension's name and visibility.
+
+The buttons located at the right side of the dialog have the following purposes:
+
+"Add" - opens \ref add_dimension_page "Add Dimension" dialog for interactive specification of a new dimension for the selected object.
+"Remove" - removes selected instance of dimension.
+"Show All" / "Hide All" - turn on/off local visibility flags of all dimensions presented in the list.
+
+
+\image html interact_with_dimensions.png
+
+Geometrical properties of the selected dimension become interactively editable in viewer.
+When hovering with mouse, the element of dimension become highlighted.
+This means that the element is ready for interactive operations.
+
+The following interactive operations are allowed:
+
+Modification of flyout length. By dragging the flyout with left mouse button the user is allowed to change its length without changing its plane (direction).
+Modification of flyout length & plane (direction). If dimension is viewed at least slightly from side, then dragging the flyout with holding ctrl key additionally enables modification of the flyout plane.
+Modification of label alignment. By dragging the label the user is allowed to change its alignment.
+
+
+The following horizontally aligned positions can be specified:
+
+Left. Label is located outside of the left flyout line.
+Right. Label is located outside of the right flyout line.
+Center. Label is centered among of the flyout lines.
+
+
+The following vertically aligned positions can be specified:
+
+On flyout line. The label is located at the side of flyout line, which is farther from the measured geometry.
+Under flyout line. The label is located at the side of flyout line, which is closer to the measured geometry.
+In center of flyout line.
+
+
+All of the modifications to the dimensions, until applied, are temporary. The "Apply" and "Apply and Close" buttons save the changes.
+
+*/
diff --git a/doc/salome/gui/GEOM/input/using_measurement_tools.doc b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
index 238b12a08..f19f43ff9 100644
--- a/doc/salome/gui/GEOM/input/using_measurement_tools.doc
+++ b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
@@ -19,7 +19,7 @@
\subpage whatis_page "WhatIs"
-\n Or to check their integrity:
+\n To check their integrity:
\subpage boundaries_page "Check Free Boundaries"
@@ -30,6 +30,13 @@
\subpage check_self_intersections_page "Detect Self-intersections"
+\n Or to measure dimensions of the shape elements:
+
+
+\subpage managing_dimensions_page "Manage Dimensions"
+\subpage add_dimension_page "Add Dimension"
+
+
\n Our TUI Scripts show how to use
\ref tui_measurement_tools_page "Measurement Tools" with TUI
commands .
diff --git a/doc/salome/gui/GEOM/input/viewing_geom_obj.doc b/doc/salome/gui/GEOM/input/viewing_geom_obj.doc
index 774dbaac2..b6b5a4f4e 100644
--- a/doc/salome/gui/GEOM/input/viewing_geom_obj.doc
+++ b/doc/salome/gui/GEOM/input/viewing_geom_obj.doc
@@ -59,6 +59,8 @@ geometrical object. TUI Command: sg.DisplayOnly(ID)
\image html image33.png
+Show all dimensions - shows all of the persistent dimensions created for the selected geometrical object.
+Hide all dimensions - hides all of the persistent dimensions created for the selected geometrical object.
Dump view - exports an object from the viewer in bmp, png,
jpg or jpeg image format.
Change background - allows to redefine the background
diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in
index 2fb47511b..269d3b366 100644
--- a/resources/SalomeApp.xml.in
+++ b/resources/SalomeApp.xml.in
@@ -69,13 +69,14 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/GEOMGUI/GEOMGUI_DimensionProperty.cxx b/src/GEOMGUI/GEOMGUI_DimensionProperty.cxx
index c9ca8337f..0191e9c23 100644
--- a/src/GEOMGUI/GEOMGUI_DimensionProperty.cxx
+++ b/src/GEOMGUI/GEOMGUI_DimensionProperty.cxx
@@ -47,6 +47,7 @@ void GEOMGUI_DimensionProperty::Length::Init( const Handle(AIS_LengthDimension)&
Flyout = theIO->GetFlyout();
TextHPos = theIO->DimensionAspect()->TextHorizontalPosition();
TextVPos = theIO->DimensionAspect()->TextVerticalPosition();
+ ArrowPos = theIO->DimensionAspect()->ArrowOrientation();
}
//=================================================================================
@@ -68,6 +69,7 @@ void GEOMGUI_DimensionProperty::Length::Update( Handle(AIS_LengthDimension)& the
Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
aStyle->SetTextHorizontalPosition( TextHPos );
aStyle->SetTextVerticalPosition( TextVPos );
+ aStyle->SetArrowOrientation( ArrowPos );
theIO->SetDimensionAspect( aStyle );
}
@@ -99,7 +101,8 @@ bool GEOMGUI_DimensionProperty::Length::operator == (const Length& theOther) con
if ( Flyout != theOther.Flyout
|| TextHPos != theOther.TextHPos
- || TextVPos != theOther.TextVPos )
+ || TextVPos != theOther.TextVPos
+ || ArrowPos != theOther.ArrowPos )
{
return false;
}
@@ -121,6 +124,7 @@ void GEOMGUI_DimensionProperty::Diameter::Init( const Handle(AIS_DiameterDimensi
Flyout = theIO->GetFlyout();
TextHPos = theIO->DimensionAspect()->TextHorizontalPosition();
TextVPos = theIO->DimensionAspect()->TextVerticalPosition();
+ ArrowPos = theIO->DimensionAspect()->ArrowOrientation();
}
//=================================================================================
@@ -154,6 +158,7 @@ void GEOMGUI_DimensionProperty::Diameter::Update( Handle(AIS_DiameterDimension)&
Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
aStyle->SetTextHorizontalPosition( TextHPos );
aStyle->SetTextVerticalPosition( TextVPos );
+ aStyle->SetArrowOrientation( ArrowPos );
theIO->SetDimensionAspect( aStyle );
}
@@ -189,7 +194,8 @@ bool GEOMGUI_DimensionProperty::Diameter::operator == (const Diameter& theOther)
if ( Flyout != theOther.Flyout
|| TextHPos != theOther.TextHPos
- || TextVPos != theOther.TextVPos )
+ || TextVPos != theOther.TextVPos
+ || ArrowPos != theOther.ArrowPos )
{
return false;
}
@@ -212,6 +218,7 @@ void GEOMGUI_DimensionProperty::Angle::Init( const Handle(AIS_AngleDimension)& t
Flyout = theIO->GetFlyout();
TextHPos = theIO->DimensionAspect()->TextHorizontalPosition();
TextVPos = theIO->DimensionAspect()->TextVerticalPosition();
+ ArrowPos = theIO->DimensionAspect()->ArrowOrientation();
}
//=================================================================================
@@ -233,6 +240,7 @@ void GEOMGUI_DimensionProperty::Angle::Update( Handle(AIS_AngleDimension)& theIO
Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
aStyle->SetTextHorizontalPosition( TextHPos );
aStyle->SetTextVerticalPosition( TextVPos );
+ aStyle->SetArrowOrientation( ArrowPos );
theIO->SetDimensionAspect( aStyle );
}
@@ -257,7 +265,8 @@ bool GEOMGUI_DimensionProperty::Angle::operator == (const Angle& theOther) const
if ( Flyout != theOther.Flyout
|| TextHPos != theOther.TextHPos
- || TextVPos != theOther.TextVPos )
+ || TextVPos != theOther.TextVPos
+ || ArrowPos != theOther.ArrowPos )
{
return false;
}
@@ -311,6 +320,15 @@ GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty( const GEOMGUI_DimensionPro
}
}
+//=================================================================================
+// function : Init constructor
+// purpose :
+//=================================================================================
+GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty( SalomeApp_Study* theStudy, const std::string& theEntry )
+{
+ LoadFromAttribute( theStudy, theEntry );
+}
+
//=================================================================================
// function : Destructor
// purpose :
@@ -463,6 +481,8 @@ void GEOMGUI_DimensionProperty::AddRecord( const RecordPtr& theRecord )
//=================================================================================
void GEOMGUI_DimensionProperty::RemoveRecord( const int theIndex )
{
+ myNames.remove( theIndex );
+ myVisibility.remove( theIndex );
myRecords.remove( theIndex );
}
@@ -472,6 +492,8 @@ void GEOMGUI_DimensionProperty::RemoveRecord( const int theIndex )
//=================================================================================
void GEOMGUI_DimensionProperty::Clear()
{
+ myNames.clear();
+ myVisibility.clear();
myRecords.clear();
}
@@ -480,8 +502,8 @@ void GEOMGUI_DimensionProperty::Clear()
// purpose :
//=================================================================================
void GEOMGUI_DimensionProperty::SetRecord( const int theIndex,
- const Handle(AIS_Dimension)& theIO,
- const gp_Ax3& theLCS )
+ const Handle(AIS_Dimension)& theIO,
+ const gp_Ax3& theLCS )
{
int aType = TypeFromIO( theIO );
@@ -588,7 +610,7 @@ int GEOMGUI_DimensionProperty::GetType( const int theIndex ) const
// purpose :
//=================================================================================
void GEOMGUI_DimensionProperty::LoadFromAttribute( SalomeApp_Study* theStudy,
- const std::string& theEntry )
+ const std::string& theEntry )
{
Clear();
@@ -647,13 +669,16 @@ void GEOMGUI_DimensionProperty::LoadFromAttribute( SalomeApp_Study* theStudy,
aLength->TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)aPacked[it++];
aLength->TextVPos = (Prs3d_DimensionTextVerticalPosition) (int)aPacked[it++];
- // point 1 [9,10,11]
+ // arrow flags [9]
+ aLength->ArrowPos = (Prs3d_DimensionArrowOrientation) (int)aPacked[it++];
+
+ // point 1 [10,11,12]
Standard_Real aFirstX = aPacked[it++];
Standard_Real aFirstY = aPacked[it++];
Standard_Real aFirstZ = aPacked[it++];
aLength->FirstPoint = gp_Pnt( aFirstX, aFirstY, aFirstZ );
- // point 2 [12,13,14]
+ // point 2 [13,14,15]
Standard_Real aSecondX = aPacked[it++];
Standard_Real aSecondY = aPacked[it++];
Standard_Real aSecondZ = aPacked[it++];
@@ -681,22 +706,25 @@ void GEOMGUI_DimensionProperty::LoadFromAttribute( SalomeApp_Study* theStudy,
aDiam->TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)aPacked[it++];
aDiam->TextVPos = (Prs3d_DimensionTextVerticalPosition) (int)aPacked[it++];
- // circle location [9,10,11]
+ // arrow flags [9]
+ aDiam->ArrowPos = (Prs3d_DimensionArrowOrientation) (int)aPacked[it++];
+
+ // circle location [10,11,12]
Standard_Real aLocX = (Standard_Real) aPacked[it++];
Standard_Real aLocY = (Standard_Real) aPacked[it++];
Standard_Real aLocZ = (Standard_Real) aPacked[it++];
- // circle normal [12,13,14]
+ // circle normal [13,14,15]
Standard_Real aNormX = (Standard_Real) aPacked[it++];
Standard_Real aNormY = (Standard_Real) aPacked[it++];
Standard_Real aNormZ = (Standard_Real) aPacked[it++];
- // x-direction [15,16,17]
+ // x-direction [16,17,18]
Standard_Real aXDirX = (Standard_Real) aPacked[it++];
Standard_Real aXDirY = (Standard_Real) aPacked[it++];
Standard_Real aXDirZ = (Standard_Real) aPacked[it++];
- // radius [18]
+ // radius [19]
Standard_Real aRadius = (Standard_Real) aPacked[it++];
gp_Ax2 anAx( gp_Pnt( aLocX, aLocY, aLocZ ),
@@ -720,22 +748,24 @@ void GEOMGUI_DimensionProperty::LoadFromAttribute( SalomeApp_Study* theStudy,
anAngle->TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)aPacked[it++];
anAngle->TextVPos = (Prs3d_DimensionTextVerticalPosition) (int)aPacked[it++];
- // point 1 [5,6,7]
+ // arrow flags [5]
+ anAngle->ArrowPos = (Prs3d_DimensionArrowOrientation) (int)aPacked[it++];
+
+ // point 1 [6,7,8]
Standard_Real aFirstX = (Standard_Real) aPacked[it++];
Standard_Real aFirstY = (Standard_Real) aPacked[it++];
Standard_Real aFirstZ = (Standard_Real) aPacked[it++];
- // point 2 [8,9,10]
+ // point 2 [9,10,11]
Standard_Real aSecondX = (Standard_Real) aPacked[it++];
Standard_Real aSecondY = (Standard_Real) aPacked[it++];
Standard_Real aSecondZ = (Standard_Real) aPacked[it++];
- // center [11,12,13]
+ // center [12,13,14]
Standard_Real aCenterX = (Standard_Real) aPacked[it++];
Standard_Real aCenterY = (Standard_Real) aPacked[it++];
Standard_Real aCenterZ = (Standard_Real) aPacked[it++];
- // points point 1 [4-6], point 2 [7-9], center [10-12]
anAngle->FirstPoint = gp_Pnt( aFirstX, aFirstY, aFirstZ );
anAngle->SecondPoint = gp_Pnt( aSecondX, aSecondY, aSecondZ );
anAngle->CenterPoint = gp_Pnt( aCenterX, aCenterY, aCenterZ );
@@ -756,7 +786,7 @@ void GEOMGUI_DimensionProperty::LoadFromAttribute( SalomeApp_Study* theStudy,
// purpose :
//=================================================================================
void GEOMGUI_DimensionProperty::SaveToAttribute( SalomeApp_Study *theStudy,
- const std::string &theEntry )
+ const std::string &theEntry )
{
_PTR(SObject) aSObj = theStudy->studyDS()->FindObjectID( theEntry );
if ( !aSObj )
@@ -806,12 +836,15 @@ void GEOMGUI_DimensionProperty::SaveToAttribute( SalomeApp_Study *theStudy,
aPacked.push_back( (double) aProps->TextHPos );
aPacked.push_back( (double) aProps->TextVPos );
- // point 1 [9,10,11]
+ // arrow flags [9]
+ aPacked.push_back( (double) aProps->ArrowPos );
+
+ // point 1 [10,11,12]
aPacked.push_back( (double) aProps->FirstPoint.X() );
aPacked.push_back( (double) aProps->FirstPoint.Y() );
aPacked.push_back( (double) aProps->FirstPoint.Z() );
- // point 2 [12,13,14]
+ // point 2 [13,14,15]
aPacked.push_back( (double) aProps->SecondPoint.X() );
aPacked.push_back( (double) aProps->SecondPoint.Y() );
aPacked.push_back( (double) aProps->SecondPoint.Z() );
@@ -837,22 +870,25 @@ void GEOMGUI_DimensionProperty::SaveToAttribute( SalomeApp_Study *theStudy,
aPacked.push_back( (double) aProps->TextHPos );
aPacked.push_back( (double) aProps->TextVPos );
- // circle location [9,10,11]
+ // arrow flags [9]
+ aPacked.push_back( (double) aProps->ArrowPos );
+
+ // circle location [10,11,12]
aPacked.push_back( (double) aProps->Circle.Location().X() );
aPacked.push_back( (double) aProps->Circle.Location().Y() );
aPacked.push_back( (double) aProps->Circle.Location().Z() );
- // circle normal [12,13,14]
+ // circle normal [13,14,15]
aPacked.push_back( (double) aProps->Circle.Axis().Direction().X() );
aPacked.push_back( (double) aProps->Circle.Axis().Direction().Y() );
aPacked.push_back( (double) aProps->Circle.Axis().Direction().Z() );
- // x-direction [15,16,17]
+ // x-direction [16,17,18]
aPacked.push_back( (double) aProps->Circle.XAxis().Direction().X() );
aPacked.push_back( (double) aProps->Circle.XAxis().Direction().Y() );
aPacked.push_back( (double) aProps->Circle.XAxis().Direction().Z() );
- // radius [18]
+ // radius [19]
aPacked.push_back( (double) aProps->Circle.Radius() );
break;
}
@@ -868,17 +904,20 @@ void GEOMGUI_DimensionProperty::SaveToAttribute( SalomeApp_Study *theStudy,
aPacked.push_back( (double) aProps->TextHPos );
aPacked.push_back( (double) aProps->TextVPos );
- // point 1 [5,6,7]
+ // arrow flags [5]
+ aPacked.push_back( (double) aProps->ArrowPos );
+
+ // point 1 [6,7,8]
aPacked.push_back( (double) aProps->FirstPoint.X() );
aPacked.push_back( (double) aProps->FirstPoint.Y() );
aPacked.push_back( (double) aProps->FirstPoint.Z() );
- // point 2 [8,9,10]
+ // point 2 [9,10,11]
aPacked.push_back( (double) aProps->SecondPoint.X() );
aPacked.push_back( (double) aProps->SecondPoint.Y() );
aPacked.push_back( (double) aProps->SecondPoint.Z() );
- // center [11,12,13]
+ // center [12,13,14]
aPacked.push_back( (double) aProps->CenterPoint.X() );
aPacked.push_back( (double) aProps->CenterPoint.Y() );
aPacked.push_back( (double) aProps->CenterPoint.Z() );
diff --git a/src/GEOMGUI/GEOMGUI_DimensionProperty.h b/src/GEOMGUI/GEOMGUI_DimensionProperty.h
index f2c5f7e58..49bbcd1b7 100644
--- a/src/GEOMGUI/GEOMGUI_DimensionProperty.h
+++ b/src/GEOMGUI/GEOMGUI_DimensionProperty.h
@@ -53,9 +53,9 @@ class SalomeApp_Study;
* (name);(is_visible);(dimension type);(dimension property list);
*
* The following packing scheme is used to store dimension data:
- * Length: (plane)[0-3] (flyout)[4] (text flags)[5-6] (p1)[7-9] (pnt2)[10-12]
- * Diam: (plane)[0-3] (flyout)[4] (text flags)[5-6] (circle loc, xdir, ydir, rad)[7-16]
- * Angle: (flyout)[0] (text flags)[1-2] (p1)[3-5] (p2)[6-8] (center)[9-11]
+ * Length: (plane)[0-3] (flyout)[4] (text flags)[5-6] (arrow flag)[7] (p1)[8-10] (pnt2)[11-13]
+ * Diam: (plane)[0-3] (flyout)[4] (text flags)[5-6] (arrow flag)[7] (circle loc, xdir, ydir, rad)[8-17]
+ * Angle: (flyout)[0] (text flags)[1-2] (arrow flag)[3] (p1)[4-6] (p2)[7-9] (center)[10-12]
*/
class Standard_EXPORT GEOMGUI_DimensionProperty
{
@@ -109,7 +109,8 @@ public:
Plane( gp::XOY() ),
Flyout( 0.0 ),
TextHPos( Prs3d_DTHP_Fit ),
- TextVPos( Prs3d_DTVP_Center )
+ TextVPos( Prs3d_DTVP_Center ),
+ ArrowPos( Prs3d_DAO_Fit )
{}
Length( const Length& theOther ) :
@@ -119,7 +120,8 @@ public:
Plane( theOther.Plane ),
Flyout( theOther.Flyout ),
TextHPos( theOther.TextHPos ),
- TextVPos( theOther.TextVPos )
+ TextVPos( theOther.TextVPos ),
+ ArrowPos( theOther.ArrowPos )
{}
~Length() {}
@@ -150,6 +152,7 @@ public:
double Flyout;
Prs3d_DimensionTextHorizontalPosition TextHPos;
Prs3d_DimensionTextVerticalPosition TextVPos;
+ Prs3d_DimensionArrowOrientation ArrowPos;
};
/*!
@@ -162,7 +165,8 @@ public:
Plane( gp::XOY() ),
Flyout( 0.0 ),
TextHPos( Prs3d_DTHP_Fit ),
- TextVPos( Prs3d_DTVP_Center )
+ TextVPos( Prs3d_DTVP_Center ),
+ ArrowPos( Prs3d_DAO_Fit )
{}
Diameter( const Diameter& theOther ) :
@@ -171,7 +175,8 @@ public:
Plane( theOther.Plane ),
Flyout( theOther.Flyout ),
TextHPos( theOther.TextHPos ),
- TextVPos( theOther.TextVPos )
+ TextVPos( theOther.TextVPos ),
+ ArrowPos( theOther.ArrowPos )
{}
~Diameter() {}
@@ -201,6 +206,7 @@ public:
double Flyout;
Prs3d_DimensionTextHorizontalPosition TextHPos;
Prs3d_DimensionTextVerticalPosition TextVPos;
+ Prs3d_DimensionArrowOrientation ArrowPos;
};
/*!
@@ -215,7 +221,8 @@ public:
CenterPoint( gp::Origin() ),
Flyout( 0.0 ),
TextHPos( Prs3d_DTHP_Fit ),
- TextVPos( Prs3d_DTVP_Center )
+ TextVPos( Prs3d_DTVP_Center ),
+ ArrowPos( Prs3d_DAO_Fit )
{}
Angle( const Angle& theOther ) :
@@ -225,7 +232,8 @@ public:
CenterPoint( theOther.CenterPoint ),
Flyout( theOther.Flyout ),
TextHPos( theOther.TextHPos ),
- TextVPos( theOther.TextVPos )
+ TextVPos( theOther.TextVPos ),
+ ArrowPos( theOther.ArrowPos )
{}
~Angle() {}
@@ -256,6 +264,7 @@ public:
double Flyout;
Prs3d_DimensionTextHorizontalPosition TextHPos;
Prs3d_DimensionTextVerticalPosition TextVPos;
+ Prs3d_DimensionArrowOrientation ArrowPos;
};
typedef QSharedPointer RecordPtr;
@@ -272,6 +281,11 @@ public:
*/
GEOMGUI_DimensionProperty( const GEOMGUI_DimensionProperty& theOther );
+ /*!
+ * \brief Constructor. Inits property from attribute.
+ */
+ GEOMGUI_DimensionProperty( SalomeApp_Study* theStudy, const std::string& theEntry );
+
/*!
* \brief Destructor.
*/
@@ -287,6 +301,14 @@ public:
*/
bool operator == (const GEOMGUI_DimensionProperty &theOther) const;
+ /*!
+ * \brief Overload comparsion.
+ */
+ bool operator != (const GEOMGUI_DimensionProperty &theOther) const
+ {
+ return !(operator == (theOther));
+ }
+
public:
/*!
diff --git a/src/GEOMGUI/GEOMGUI_Selection.cxx b/src/GEOMGUI/GEOMGUI_Selection.cxx
index d1bdf3767..009c1565c 100644
--- a/src/GEOMGUI/GEOMGUI_Selection.cxx
+++ b/src/GEOMGUI/GEOMGUI_Selection.cxx
@@ -24,6 +24,7 @@
// Author : Alexander SOLOVYOV, Open CASCADE S.A.S. (alexander.solovyov@opencascade.com)
#include "GEOMGUI_Selection.h"
+#include
#include "GeometryGUI.h"
#include "GEOM_Displayer.h"
@@ -178,6 +179,10 @@ QVariant GEOMGUI_Selection::parameter( const int idx, const QString& p ) const
v = isPhysicalMaterial(idx);
else if ( p == "isFolder" )
v = isFolder(idx);
+ else if ( p == "hasHiddenDimensions" )
+ v = hasHiddenDimensions(idx);
+ else if ( p == "hasVisibleDimensions" )
+ v = hasVisibleDimensions(idx);
else
v = LightApp_Selection::parameter( idx, p );
@@ -682,3 +687,59 @@ bool GEOMGUI_Selection::isFolder( const int index ) const
return res;
}
+bool GEOMGUI_Selection::hasDimensions( const int theIndex, bool& theHidden, bool& theVisible ) const
+{
+ SalomeApp_Study* appStudy = dynamic_cast( study() );
+
+ if ( !appStudy )
+ {
+ return false;
+ }
+
+ QString anEntry = entry( theIndex );
+ _PTR(Study) aStudy = appStudy->studyDS();
+ if ( !aStudy || anEntry.isNull() )
+ {
+ return false;
+ }
+
+ GEOMGUI_DimensionProperty aDimensions( appStudy, anEntry.toStdString() );
+
+ theHidden = false;
+ theVisible = false;
+
+ for ( int it = 0; it < aDimensions.GetNumber(); ++it )
+ {
+ if ( aDimensions.IsVisible( it ) )
+ theVisible = true;
+ else
+ theHidden = true;
+ }
+
+ return aDimensions.GetNumber() > 0;
+}
+
+bool GEOMGUI_Selection::hasHiddenDimensions( const int theIndex ) const
+{
+ bool isAnyVisible = false;
+ bool isAnyHidden = false;
+ if ( !hasDimensions( theIndex, isAnyHidden, isAnyVisible ) )
+ {
+ return false;
+ }
+
+ return isAnyHidden;
+}
+
+bool GEOMGUI_Selection::hasVisibleDimensions( const int theIndex ) const
+{
+ bool isAnyVisible = false;
+ bool isAnyHidden = false;
+ if ( !hasDimensions( theIndex, isAnyHidden, isAnyVisible ) )
+ {
+ return false;
+ }
+
+ return isAnyVisible;
+}
+
diff --git a/src/GEOMGUI/GEOMGUI_Selection.h b/src/GEOMGUI/GEOMGUI_Selection.h
index b2738f75f..a9c17665e 100644
--- a/src/GEOMGUI/GEOMGUI_Selection.h
+++ b/src/GEOMGUI/GEOMGUI_Selection.h
@@ -78,6 +78,11 @@ private:
bool isComponent( const int ) const;
bool isFolder( const int ) const;
+
+ bool hasDimensions( const int, bool&, bool& ) const;
+ bool hasHiddenDimensions( const int ) const;
+ bool hasVisibleDimensions( const int ) const;
+
GEOM::GEOM_Object_ptr getObject( const int ) const;
GEOM::GEOM_BaseObject_ptr getBaseObject( const int ) const;
diff --git a/src/GEOMGUI/GEOM_Displayer.cxx b/src/GEOMGUI/GEOM_Displayer.cxx
index 2683c9603..77138e280 100644
--- a/src/GEOMGUI/GEOM_Displayer.cxx
+++ b/src/GEOMGUI/GEOM_Displayer.cxx
@@ -1100,6 +1100,7 @@ void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& t
aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
aStyle->MakeText3d( Standard_True );
aStyle->MakeTextShaded( Standard_True );
+ aStyle->SetExtensionSize( aFontHeight * 0.5 );
aStyle->TextAspect()->SetHeight( aFontHeight );
aStyle->ArrowAspect()->SetLength( anArrowLength );
aStyle->LineAspect()->SetWidth( aLineWidth );
@@ -1107,6 +1108,28 @@ void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& t
aStyle->SetTextVerticalPosition( aPrs->DimensionAspect()->TextVerticalPosition() );
aPrs->SetDimensionAspect( aStyle );
aPrs->SetPolygonOffsets( Aspect_POM_Fill, -1.0, -1.0 );
+ aPrs->Attributes()->SetDimLengthDisplayUnits( aUnitsLength.toLatin1().data() );
+ aPrs->Attributes()->SetDimAngleDisplayUnits( aUnitsAngle.toLatin1().data() );
+
+ if ( aPrs->IsKind( STANDARD_TYPE(AIS_AngleDimension) ) )
+ {
+ // show degree symbol for dimension instead of label "deg"
+ if ( aUnitsAngle == "deg" )
+ {
+ aPrs->SetSpecialSymbol(0xB0);
+ aPrs->SetDisplaySpecialSymbol( isUnitsShown ? AIS_DSS_After : AIS_DSS_No );
+ aStyle->MakeUnitsDisplayed(Standard_False);
+ }
+ else
+ {
+ aPrs->SetDisplaySpecialSymbol(AIS_DSS_No);
+ aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
+ }
+ }
+ else
+ {
+ aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
+ }
aListOfIO.Append( aPrs );
}
diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts
index e62e0794d..8aade3c3d 100644
--- a/src/GEOMGUI/GEOM_msg_en.ts
+++ b/src/GEOMGUI/GEOM_msg_en.ts
@@ -3276,6 +3276,10 @@ Please, select face, shell or solid and try again
PREF_DIMENSIONS_ANGLE_UNITS
Angle measurement units
+
+ PREF_DIMENSIONS_DEFAULT_FLYOUT
+ Default flyout length
+
PREF_DIMENSIONS_SHOW_UNITS
Show units of measurement
@@ -4732,6 +4736,30 @@ Please, select face, shell or solid and try again
STB_MANAGE_DIMENSIONS
Manage measurement dimensions of an object
+
+ MEN_POP_SHOW_ALL_DIMENSIONS
+ Show all dimensions
+
+
+ STB_POP_SHOW_ALL_DIMENSIONS
+ Show all hidden measures (dimension) created for the object
+
+
+ TOP_POP_SHOW_ALL_DIMENSIONS
+ Show all hidden measures (dimension) created for the object
+
+
+ MEN_POP_HIDE_ALL_DIMENSIONS
+ Hide all dimensions
+
+
+ STB_POP_HIDE_ALL_DIMENSIONS
+ Show all visible measures (dimension) created for the object
+
+
+ TOP_POP_HIDE_ALL_DIMENSIONS
+ Show all visible measures (dimension) created for the object
+
TOP_POP_AUTO_COLOR
Auto color
@@ -6166,6 +6194,16 @@ Number of sketch points too small
WRN_TITLE_UNSAVED
Unsaved changes
+
+ WRN_MSG_CHANGES_LOST
+ The unsaved changes will be lost.
+Do you wish to continue?
+
+
+ WRN_MSG_CHANGES_SAVE
+ The unsaved changes will be lost.
+Do you wish to save them?
+
WRN_MSG_UNSAVED
The unsaved changes will be lost.
diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts
index dd5a103c7..ee3e881d8 100644
--- a/src/GEOMGUI/GEOM_msg_fr.ts
+++ b/src/GEOMGUI/GEOM_msg_fr.ts
@@ -3276,6 +3276,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
PREF_DIMENSIONS_ANGLE_UNITS
Angle measurement units
+
+ PREF_DIMENSIONS_DEFAULT_FLYOUT
+ Default flyout length
+
PREF_DIMENSIONS_SHOW_UNITS
Show units of measurement
@@ -4732,6 +4736,30 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
STB_MANAGE_DIMENSIONS
Manage measurement dimensions of an object
+
+ MEN_POP_SHOW_ALL_DIMENSIONS
+ Show all dimensions
+
+
+ STB_POP_SHOW_ALL_DIMENSIONS
+ Show all hidden measures (dimension) created for the object
+
+
+ TOP_POP_SHOW_ALL_DIMENSIONS
+ Show all hidden measures (dimension) created for the object
+
+
+ MEN_POP_HIDE_ALL_DIMENSIONS
+ Hide all dimensions
+
+
+ STB_POP_HIDE_ALL_DIMENSIONS
+ Show all visible measures (dimension) created for the object
+
+
+ TOP_POP_HIDE_ALL_DIMENSIONS
+ Show all visible measures (dimension) created for the object
+
TOP_POP_AUTO_COLOR
Couleur automatique
@@ -6166,6 +6194,16 @@ Le nombre de points n'est pas suffisant
WRN_TITLE_UNSAVED
Unsaved changes
+
+ WRN_MSG_CHANGES_LOST
+ The unsaved changes will be lost.
+Do you wish to continue?
+
+
+ WRN_MSG_CHANGES_SAVE
+ The unsaved changes will be lost.
+Do you wish to save them?
+
WRN_MSG_UNSAVED
The unsaved changes will be lost.
diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts
index c3b84b8f6..7837cffaf 100644
--- a/src/GEOMGUI/GEOM_msg_ja.ts
+++ b/src/GEOMGUI/GEOM_msg_ja.ts
@@ -3271,6 +3271,10 @@
PREF_DIMENSIONS_ANGLE_UNITS
Angle measurement units
+
+ PREF_DIMENSIONS_DEFAULT_FLYOUT
+ Default flyout length
+
PREF_DIMENSIONS_SHOW_UNITS
Show units of measurement
@@ -4727,6 +4731,30 @@
STB_MANAGE_DIMENSIONS
Manage measurement dimensions of an object
+
+ MEN_POP_SHOW_ALL_DIMENSIONS
+ Show all dimensions
+
+
+ STB_POP_SHOW_ALL_DIMENSIONS
+ Show all hidden measures (dimension) created for the object
+
+
+ TOP_POP_SHOW_ALL_DIMENSIONS
+ Show all hidden measures (dimension) created for the object
+
+
+ MEN_POP_HIDE_ALL_DIMENSIONS
+ Hide all dimensions
+
+
+ STB_POP_HIDE_ALL_DIMENSIONS
+ Show all visible measures (dimension) created for the object
+
+
+ TOP_POP_HIDE_ALL_DIMENSIONS
+ Show all visible measures (dimension) created for the object
+
TOP_POP_AUTO_COLOR
自動色
@@ -6158,6 +6186,16 @@
WRN_TITLE_UNSAVED
Unsaved changes
+
+ WRN_MSG_CHANGES_LOST
+ The unsaved changes will be lost.
+Do you wish to continue?
+
+
+ WRN_MSG_CHANGES_SAVE
+ The unsaved changes will be lost.
+Do you wish to save them?
+
WRN_MSG_UNSAVED
The unsaved changes will be lost.
diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx
index bd3e7e5c0..f8c4a8268 100644
--- a/src/GEOMGUI/GeometryGUI.cxx
+++ b/src/GEOMGUI/GeometryGUI.cxx
@@ -635,6 +635,8 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam )
case GEOMOp::OpPointCoordinates: // MENU MEASURE - POINT COORDINATES
case GEOMOp::OpCheckSelfInters: // MENU MEASURE - CHECK SELF INTERSECTIONS
case GEOMOp::OpManageDimensions: // MENU MEASURE - MANAGE DIMENSIONS
+ case GEOMOp::OpShowAllDimensions: // POPUP MENU - SHOW ALL DIMENSIONS
+ case GEOMOp::OpHideAllDimensions: // POPUP MENU - HIDE ALL DIMENSIONS
libName = "MeasureGUI";
break;
case GEOMOp::OpGroupCreate: // MENU GROUP - CREATE
@@ -1071,6 +1073,8 @@ void GeometryGUI::initialize( CAM_Application* app )
createGeomAction( GEOMOp::OpPredefMaterCustom, "POP_PREDEF_MATER_CUSTOM" );
createGeomAction( GEOMOp::OpCreateFolder, "POP_CREATE_FOLDER" );
createGeomAction( GEOMOp::OpSortChildren, "POP_SORT_CHILD_ITEMS" );
+ createGeomAction( GEOMOp::OpShowAllDimensions, "POP_SHOW_ALL_DIMENSIONS" );
+ createGeomAction( GEOMOp::OpHideAllDimensions, "POP_HIDE_ALL_DIMENSIONS" );
// Create actions for increase/decrease transparency shortcuts
createGeomAction( GEOMOp::OpIncrTransparency, "", "", 0, false,
@@ -1588,6 +1592,14 @@ void GeometryGUI::initialize( CAM_Application* app )
mgr->insert( action(GEOMOp::OpShowOnlyChildren ), -1, -1 ); // display only children
mgr->setRule(action(GEOMOp::OpShowOnlyChildren ), (canDisplay + "and ($type in {%1}) and client='ObjectBrowser' and hasChildren=true").arg( types ), QtxPopupMgr::VisibleRule );
+ QString aDimensionRule = "($component={'GEOM'}) and selcount=1 and isVisible and type='Shape' and %1";
+
+ mgr->insert( separator(), -1, -1 ); // -----------
+ mgr->insert( action( GEOMOp::OpShowAllDimensions ), -1, -1 ); // show all dimensions
+ mgr->setRule( action( GEOMOp::OpShowAllDimensions ), aDimensionRule.arg( "hasHiddenDimensions" ), QtxPopupMgr::VisibleRule );
+ mgr->insert( action( GEOMOp::OpHideAllDimensions ), -1, -1 ); // hide all dimensions
+ mgr->setRule( action( GEOMOp::OpHideAllDimensions ), aDimensionRule.arg( "hasVisibleDimensions" ), QtxPopupMgr::VisibleRule );
+
mgr->insert( separator(), -1, -1 ); // -----------
mgr->insert( action( GEOMOp::OpUnpublishObject ), -1, -1 ); // Unpublish object
mgr->setRule( action( GEOMOp::OpUnpublishObject ), QString("client='ObjectBrowser' and $type in {'Shape' 'Group' 'Field' 'FieldStep'} and selcount>0"), QtxPopupMgr::VisibleRule );
@@ -2375,11 +2387,19 @@ void GeometryGUI::createPreferences()
setPreferenceProperty( aDimLineWidthId, "min", 1 );
setPreferenceProperty( aDimLineWidthId, "max", 5 );
- addPreference( tr( "PREF_DIMENSIONS_FONT_HEIGHT" ), aDimGroupId,
- LightApp_Preferences::DblSpin, "Geometry", "dimensions_font_height" );
+ int aDimFontHeightId = addPreference( tr( "PREF_DIMENSIONS_FONT_HEIGHT" ), aDimGroupId,
+ LightApp_Preferences::DblSpin, "Geometry", "dimensions_font_height" );
- addPreference( tr( "PREF_DIMENSIONS_ARROW_LENGTH" ), aDimGroupId,
- LightApp_Preferences::IntSpin, "Geometry", "dimensions_arrow_length" );
+ setPreferenceProperty( aDimFontHeightId, "min", 1e-9 );
+ setPreferenceProperty( aDimFontHeightId, "max", 1e+9 );
+ setPreferenceProperty( aDimFontHeightId, "precision", 9 );
+
+ int aDimArrLengthId = addPreference( tr( "PREF_DIMENSIONS_ARROW_LENGTH" ), aDimGroupId,
+ LightApp_Preferences::DblSpin, "Geometry", "dimensions_arrow_length" );
+
+ setPreferenceProperty( aDimArrLengthId, "min", 1e-9 );
+ setPreferenceProperty( aDimArrLengthId, "max", 1e+9 );
+ setPreferenceProperty( aDimArrLengthId, "precision", 9 );
int aLengthUnitsId = addPreference( tr( "PREF_DIMENSIONS_LENGTH_UNITS" ), aDimGroupId,
LightApp_Preferences::Selector, "Geometry", "dimensions_length_units" );
@@ -2404,6 +2424,13 @@ void GeometryGUI::createPreferences()
setPreferenceProperty( aLengthUnitsId, "strings", aListOfLengthUnits );
setPreferenceProperty( anAngUnitsId, "strings", aListOfAngUnits );
+ int aDimDefFlyout = addPreference( tr( "PREF_DIMENSIONS_DEFAULT_FLYOUT" ), aDimGroupId,
+ LightApp_Preferences::DblSpin, "Geometry", "dimensions_default_flyout" );
+
+ setPreferenceProperty( aDimDefFlyout, "min", 1e-9 );
+ setPreferenceProperty( aDimDefFlyout, "max", 1e+9 );
+ setPreferenceProperty( aDimDefFlyout, "precision", 9 );
+
int isoGroup = addPreference( tr( "PREF_ISOS" ), tabId );
setPreferenceProperty( isoGroup, "columns", 2 );
int isoU = addPreference( tr( "PREF_ISOS_U" ), isoGroup,
diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h
index d24ba7d8e..d63d3c7fd 100644
--- a/src/GEOMGUI/GeometryGUI_Operations.h
+++ b/src/GEOMGUI/GeometryGUI_Operations.h
@@ -190,6 +190,8 @@ namespace GEOMOp {
OpCheckSelfInters = 5012, // MENU MEASURES - CHECK SELF INTERSECTIONS
OpGetNonBlocks = 5013, // MENU MEASURES - GET NON BLOCKS
OpManageDimensions = 5014, // MENU MEASURES - MANAGE DIMENSIONS
+ OpShowAllDimensions = 5015, // POPUP MENU - SHOW ALL DIMENSIONS
+ OpHideAllDimensions = 5016, // POPUP MENU - HIDE ALL DIMENSIONS
// GroupGUI --------------------//--------------------------------
OpGroupCreate = 6000, // MENU GROUP - CREATE
OpGroupEdit = 6001, // MENU GROUP - EDIT
diff --git a/src/MeasureGUI/MeasureGUI.cxx b/src/MeasureGUI/MeasureGUI.cxx
index e079e74bc..dea595628 100644
--- a/src/MeasureGUI/MeasureGUI.cxx
+++ b/src/MeasureGUI/MeasureGUI.cxx
@@ -28,8 +28,14 @@
#include
#include "GeometryGUI_Operations.h"
+
+#include
+
+#include
+#include
#include
#include
+#include
#include "MeasureGUI_PropertiesDlg.h" // Method PROPERTIES
#include "MeasureGUI_CenterMassDlg.h" // Method CENTER MASS
@@ -124,6 +130,12 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
case GEOMOp::OpManageDimensions:
dlg = new MeasureGUI_ManageDimensionsDlg( getGeometryGUI(), parent );
break; // MANAGE DIMENSIONS
+ case GEOMOp::OpShowAllDimensions:
+ ChangeDimensionsVisibility( true );
+ break; // SHOW ALL DIMENSIONS
+ case GEOMOp::OpHideAllDimensions:
+ ChangeDimensionsVisibility( false );
+ break; // HIDE ALL DIMENSIONS
default:
app->putInfo( tr( "GEOM_PRP_COMMAND" ).arg( theCommandID ) );
break;
@@ -136,6 +148,56 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
return true;
}
+//=======================================================================
+// function : ChangeDimensionsVisibility
+// purpose :
+//=======================================================================
+void MeasureGUI::ChangeDimensionsVisibility( const bool theIsVisible )
+{
+ SalomeApp_Application* anApp = getGeometryGUI()->getApp();
+ if (!anApp)
+ {
+ return;
+ }
+
+ SalomeApp_Study* anActiveStudy = dynamic_cast( anApp->activeStudy() );
+ if ( !anActiveStudy )
+ {
+ return;
+ }
+
+ LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
+ if ( !aSelMgr )
+ {
+ return;
+ }
+
+ SALOME_ListIO aListIO;
+ aSelMgr->selectedObjects( aListIO );
+ if ( aListIO.Extent() != 1 )
+ {
+ return;
+ }
+
+ Handle(SALOME_InteractiveObject) anIObject = aListIO.First();
+ if ( !anIObject->hasEntry() )
+ {
+ return;
+ }
+
+ SUIT_OverrideCursor();
+
+ GEOMGUI_DimensionProperty aDimensions( anActiveStudy, anIObject->getEntry() );
+
+ for ( int anIt = 0; anIt < aDimensions.GetNumber(); ++anIt )
+ {
+ aDimensions.SetVisible( anIt, theIsVisible );
+ }
+
+ aDimensions.SaveToAttribute( anActiveStudy, anIObject->getEntry() );
+
+ GEOM_Displayer( anActiveStudy ).Redisplay( anIObject, true );
+}
//=====================================================================================
// EXPORTED METHODS
diff --git a/src/MeasureGUI/MeasureGUI.h b/src/MeasureGUI/MeasureGUI.h
index 4ab843810..fc909da1d 100644
--- a/src/MeasureGUI/MeasureGUI.h
+++ b/src/MeasureGUI/MeasureGUI.h
@@ -46,6 +46,9 @@ public:
~MeasureGUI();
bool OnGUIEvent( int, SUIT_Desktop* );
+
+ // Show/hide all dimension created for object
+ void ChangeDimensionsVisibility( const bool theIsVisible );
};
#endif // MEASUREGUI_H
diff --git a/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx b/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx
index 4daaf6039..5da50d8a3 100644
--- a/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx
+++ b/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx
@@ -34,6 +34,9 @@
#include
#include
+#include
+#include
+#include
#include
#include
#include
@@ -127,7 +130,13 @@ MeasureGUI_CreateDimensionDlg::MeasureGUI_CreateDimensionDlg( const GEOM::GeomOb
myDimensionInteractor = new MeasureGUI_DimensionInteractor( theGUI, theParent );
+ myDiameterArgs->setVisible( false );
+ myAngleArgs ->setVisible( false );
+ myLengthArgs ->setVisible( true );
+
Init();
+
+ setHelpFileName("add_dimension_page.html");
}
//=================================================================================
@@ -404,6 +413,7 @@ void MeasureGUI_CreateDimensionDlg::StartLocalEditing()
anAISContext->SetZLayer( myDimension, myEditingLayer );
anAISContext->Activate( myDimension, AIS_DSM_Line );
anAISContext->Activate( myDimension, AIS_DSM_Text );
+ anAISContext->Redisplay( myDimension );
}
//=================================================================================
@@ -434,14 +444,15 @@ void MeasureGUI_CreateDimensionDlg::StopLocalEditing()
//=================================================================================
void MeasureGUI_CreateDimensionDlg::Init()
{
+ myDimension = NULL;
+
StopLocalEditing();
erasePreview();
- myDiameterArgs->setVisible( false );
- myAngleArgs ->setVisible( false );
- myLengthArgs ->setVisible( true );
+ myDiameterArgs->Reset();
myLengthArgs->Reset();
+ myAngleArgs->Reset();
myRBGroup->button( TypeButtonID_Length )->click();
}
@@ -461,11 +472,28 @@ Handle(AIS_Dimension) MeasureGUI_CreateDimensionDlg::CreateDimension()
int aLineWidth = aResMgr->integerValue( "Geometry", "dimensions_line_width", 1 );
double aFontHeight = aResMgr->doubleValue ( "Geometry", "dimensions_font_height", 10 );
double anArrowLength = aResMgr->doubleValue ( "Geometry", "dimensions_arrow_length", 5 );
+ double aDefFlyout = aResMgr->doubleValue ( "Geometry", "dimensions_default_flyout", 20 );
bool isUnitsShown = aResMgr->booleanValue( "Geometry", "dimensions_show_units", false );
QString aUnitsLength = aResMgr->stringValue ( "Geometry", "dimensions_length_units", "m" );
QString aUnitsAngle = aResMgr->stringValue ( "Geometry", "dimensions_angle_units", "deg" );
- MeasureGUI_DimensionCreateTool aTool( myGeomGUI );
+ OCCViewer_ViewWindow* anActiveView = NULL;
+
+ SalomeApp_Application* anApp = myGeomGUI->getApp();
+
+ if ( anApp )
+ {
+ OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) anApp->getViewManager( OCCViewer_Viewer::Type(), false );
+ if ( aViewMgr )
+ {
+ anActiveView = (OCCViewer_ViewWindow*) aViewMgr->getActiveView();
+ }
+ }
+
+ MeasureGUI_DimensionCreateTool aTool;
+
+ aTool.Settings.DefaultFlyout = aDefFlyout;
+ aTool.Settings.ActiveView = anActiveView ? anActiveView->getViewPort()->getView() : NULL;
switch ( getConstructorId() )
{
@@ -559,9 +587,33 @@ Handle(AIS_Dimension) MeasureGUI_CreateDimensionDlg::CreateDimension()
aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
aStyle->MakeText3d( Standard_True );
aStyle->MakeTextShaded( Standard_True );
+ aStyle->SetExtensionSize( aFontHeight * 0.5 );
aStyle->TextAspect()->SetHeight( aFontHeight );
aStyle->ArrowAspect()->SetLength( anArrowLength );
aStyle->LineAspect()->SetWidth( aLineWidth );
+
+ if ( aDimensionIO->IsKind( STANDARD_TYPE(AIS_AngleDimension) ) )
+ {
+ // show degree symbol for dimension instead of label "deg"
+ if ( aUnitsAngle == "deg" )
+ {
+ aDimensionIO->SetSpecialSymbol(0xB0);
+ aDimensionIO->SetDisplaySpecialSymbol( isUnitsShown ? AIS_DSS_After : AIS_DSS_No );
+ aStyle->MakeUnitsDisplayed(Standard_False);
+ }
+ else
+ {
+ aDimensionIO->SetDisplaySpecialSymbol(AIS_DSS_No);
+ aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
+ }
+ }
+ else
+ {
+ aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
+ }
+
+ aDimensionIO->Attributes()->SetDimLengthDisplayUnits( aUnitsLength.toLatin1().data() );
+ aDimensionIO->Attributes()->SetDimAngleDisplayUnits( aUnitsAngle.toLatin1().data() );
aDimensionIO->SetDimensionAspect( aStyle );
aDimensionIO->SetPolygonOffsets( Aspect_POM_Fill, -1.0, -1.0 );
diff --git a/src/MeasureGUI/MeasureGUI_DimensionCreateTool.cxx b/src/MeasureGUI/MeasureGUI_DimensionCreateTool.cxx
index c32d0c9ca..087e3e810 100644
--- a/src/MeasureGUI/MeasureGUI_DimensionCreateTool.cxx
+++ b/src/MeasureGUI/MeasureGUI_DimensionCreateTool.cxx
@@ -41,14 +41,28 @@
// OCCT includes
#include
#include
+#include
#include
+#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
#include
+#include
#include
+#include
#include
#include
#include
+#include
+#include
+#include
+#include
#include
#include
#include
@@ -58,36 +72,38 @@
#include
#include
#include
+#include
#include
-#include
#include
//=================================================================================
// function : Constructor
// purpose :
//=================================================================================
-MeasureGUI_DimensionCreateTool::MeasureGUI_DimensionCreateTool( GeometryGUI* theGeomGUI )
-: myGeomGUI( theGeomGUI )
+MeasureGUI_DimensionCreateTool::MeasureGUI_DimensionCreateTool()
{
+ Settings.DefaultFlyout = 0.0;
+ Settings.ActiveView = NULL;
}
//=================================================================================
// function : LengthOnEdge
// purpose :
//=================================================================================
-Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthOnEdge( const GEOM::GeomObjPtr& theEdge )
+Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthOnEdge( const GEOM::GeomObjPtr& theMeasuredObj ) const
{
/* ---------------------------------------------------------------- *
* get the edge and parent shape *
* ---------------------------------------------------------------- */
- TopoDS_Shape aShapeEdge;
- TopoDS_Shape aShapeMain;
- if ( !GEOMBase::GetShape( theEdge.get(), aShapeEdge ) )
+ TopoDS_Shape aMeasuredShape;
+ TopoDS_Shape aMainShape;
+ if ( !GEOMBase::GetShape( theMeasuredObj.operator ->(), aMeasuredShape ) )
{
return NULL;
}
- if ( !GEOMBase::GetShape( GetMainShape( theEdge ).get(), aShapeMain ) )
+
+ if ( !GEOMBase::GetShape( GetMainShape( theMeasuredObj ).get(), aMainShape ) )
{
return NULL;
}
@@ -96,7 +112,7 @@ Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthOnEdge( const
/* check the input geometry */
/* ------------------------------------------------- */
- TopoDS_Edge anEdge = TopoDS::Edge( aShapeEdge );
+ TopoDS_Edge anEdge = TopoDS::Edge( aMeasuredShape );
TopoDS_Vertex aVertex1;
TopoDS_Vertex aVertex2;
@@ -109,59 +125,85 @@ Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthOnEdge( const
return NULL;
}
- /* ------------------------------------------------- *
- * compose list of possible flyout directions *
- * ------------------------------------------------- */
+ /* ------------------------- *
+ * position the dimension
+ * ------------------------- */
Bnd_Box aBnd;
- BRepBndLib::AddClose( aShapeMain, aBnd );
+ BRepBndLib::AddClose( aMainShape, aBnd );
- TColgp_SequenceOfDir aSeqOfFlyout;
- ChooseLengthFlyoutsFromShape( aSeqOfFlyout, anEdge, aShapeMain );
- ChooseLengthFlyoutsFromBnd( aSeqOfFlyout, aPnt1, aPnt2, aBnd );
- if ( aSeqOfFlyout.IsEmpty() )
+ // get face sides
+ TopTools_IndexedDataMapOfShapeListOfShape aRelationMap;
+ TopExp::MapShapesAndAncestors( aMainShape, TopAbs_EDGE, TopAbs_FACE, aRelationMap );
+ const TopTools_ListOfShape& aRelatedFaces = aRelationMap.FindFromKey( anEdge );
+
+ gp_Vec aFaceN1( gp::Origin(), gp::Origin() );
+ gp_Vec aFaceN2( gp::Origin(), gp::Origin() );
+ gp_Vec aFaceS1( gp::Origin(), gp::Origin() );
+ gp_Vec aFaceS2( gp::Origin(), gp::Origin() );
+
+ gp_Pnt aMiddlePnt = gp_Pnt( ( aPnt1.XYZ() + aPnt2.XYZ() ) * 0.5 );
+
+ TopTools_ListIteratorOfListOfShape aFaceIt( aRelatedFaces );
+
+ // get face side directions
+ if ( aFaceIt.More() )
{
- return NULL;
- }
+ TopoDS_Face aFace = TopoDS::Face( aFaceIt.Value() );
- gp_Dir aPointDir = gce_MakeDir( aPnt1, aPnt2 );
-
- // make planes for dimension presentation according to flyout directions
- NCollection_Sequence aSeqOfPlanes;
- for ( Standard_Integer aFlyoutIt = 1; aFlyoutIt <= aSeqOfFlyout.Length(); ++aFlyoutIt )
- {
- gp_Pln aPlane( aPnt1, aPointDir ^ aSeqOfFlyout.Value( aFlyoutIt ) );
- aSeqOfPlanes.Append( aPlane );
- }
-
- /* --------------------------------------------------------------------- *
- * select best matching dimension plane for view projection *
- * --------------------------------------------------------------------- */
-
- OCCViewer_ViewWindow* anActiveView = NULL;
-
- if ( myGeomGUI != NULL )
- {
- SalomeApp_Application* anApp = myGeomGUI->getApp();
- if ( !anApp )
+ gp_Dir aSideDir;
+ if ( GetFaceSide( aFace, anEdge, aSideDir ) )
{
- OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) anApp->getViewManager( OCCViewer_Viewer::Type(), false );
- if ( aViewMgr )
- {
- anActiveView = (OCCViewer_ViewWindow*) aViewMgr->getActiveView();
- }
+ aFaceS1 = aSideDir;
+ }
+
+ Handle(Geom_Surface) aSurface = BRep_Tool::Surface( aFace );
+
+ Standard_Real aU = 0.0, aV = 0.0;
+ GeomLib_Tool::Parameters( aSurface, aMiddlePnt, Precision::Confusion(), aU, aV );
+
+ gp_Dir aNorm;
+ if ( GeomLib::NormEstim( aSurface, gp_Pnt2d( aU, aV ), Precision::Confusion(), aNorm ) <= 1 )
+ {
+ aFaceN1 = aFace.Orientation() == TopAbs_REVERSED ? -aNorm : aNorm;
+ }
+
+ aFaceIt.Next();
+ }
+
+ if ( aFaceIt.More() )
+ {
+ TopoDS_Face aFace = TopoDS::Face( aFaceIt.Value() );
+
+ gp_Dir aSideDir;
+ if ( GetFaceSide( aFace, anEdge, aSideDir ) )
+ {
+ aFaceS2 = aSideDir;
+ }
+
+ Handle(Geom_Surface) aSurface = BRep_Tool::Surface( aFace );
+
+ Standard_Real aU = 0.0, aV = 0.0;
+ GeomLib_Tool::Parameters( aSurface, aMiddlePnt, Precision::Confusion(), aU, aV );
+
+ gp_Dir aNorm;
+ if ( GeomLib::NormEstim( aSurface, gp_Pnt2d( aU, aV ), Precision::Confusion(), aNorm ) <= 1 )
+ {
+ aFaceN2 = aFace.Orientation() == TopAbs_REVERSED ? -aNorm : aNorm;
}
}
- gp_Pln aChoosenPlane = anActiveView
- ? SelectPlaneForProjection( aSeqOfPlanes, anActiveView->getViewPort()->getView() )
- : aSeqOfPlanes.First();
+ gp_Pln aPln;
+ PositionLength( aBnd, aFaceN1, aFaceN2, aFaceS1, aFaceS2, aPnt1, aPnt2, aPln );
- /* ------------------------------------------------------------------------------------ *
- * construct interactive presentation *
- * ------------------------------------------------------------------------------------ */
+ /* --------------------------------------------------------- *
+ * construct the dimension for the best selected position
+ * --------------------------------------------------------- */
+
+ Handle(AIS_LengthDimension) aDimension = new AIS_LengthDimension( anEdge, aPln );
+
+ aDimension->SetFlyout( Settings.DefaultFlyout );
- Handle(AIS_LengthDimension) aDimension = new AIS_LengthDimension( anEdge, aChoosenPlane );
if ( !aDimension->IsValid() )
{
return NULL;
@@ -174,45 +216,155 @@ Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthOnEdge( const
// function : LengthByPoints
// purpose :
//=================================================================================
-Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthByPoints( const GEOM::GeomObjPtr& thePoint1,
- const GEOM::GeomObjPtr& thePoint2 )
+Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthByPoints( const GEOM::GeomObjPtr& theMeasuredObj1,
+ const GEOM::GeomObjPtr& theMeasuredObj2 ) const
{
- TopoDS_Shape aFirstSh;
- if ( !GEOMBase::GetShape( thePoint1.operator ->(), aFirstSh ) )
+ /* ---------------------------------------------------------------- *
+ * get the edge and parent shape *
+ * ---------------------------------------------------------------- */
+
+ TopoDS_Shape aMeasuredShape1;
+ TopoDS_Shape aMeasuredShape2;
+ TopoDS_Shape aMainShape;
+
+ if ( !GEOMBase::GetShape( theMeasuredObj1.operator ->(), aMeasuredShape1 ) )
{
return NULL;
}
- TopoDS_Shape aSecondSh;
- if ( !GEOMBase::GetShape( thePoint2.operator ->(), aSecondSh ) )
+ if ( !GEOMBase::GetShape( theMeasuredObj2.operator ->(), aMeasuredShape2 ) )
{
return NULL;
}
- TopoDS_Vertex aFirstVertex = TopoDS::Vertex( aFirstSh );
- TopoDS_Vertex aSecondVertex = TopoDS::Vertex( aSecondSh );
-
- gp_Pnt aPnt1 = BRep_Tool::Pnt( aFirstVertex );
- gp_Pnt aPnt2 = BRep_Tool::Pnt( aSecondVertex );
-
- gp_Vec aDir( aPnt1, aPnt2 );
- gp_Dir aUnitVecs[] = { gp::DZ(), gp::DY(), gp::DX() };
- int aUnitVecIt = 0;
- for ( ; aUnitVecIt < 3; ++aUnitVecIt )
+ if ( !GEOMBase::GetShape( GetMainShape( theMeasuredObj1 ).get(), aMainShape ) )
{
- if ( aDir.Dot( aUnitVecs[aUnitVecIt] ) <= 0.5 )
+ return NULL;
+ }
+
+ /* ------------------------------------------------- */
+ /* check the input geometry */
+ /* ------------------------------------------------- */
+
+ TopoDS_Vertex aVertex1 = TopoDS::Vertex( aMeasuredShape1 );
+ TopoDS_Vertex aVertex2 = TopoDS::Vertex( aMeasuredShape2 );
+
+ gp_Pnt aPnt1 = BRep_Tool::Pnt( aVertex1 );
+ gp_Pnt aPnt2 = BRep_Tool::Pnt( aVertex2 );
+ if ( aPnt1.Distance( aPnt2 ) <= Precision::Confusion() )
+ {
+ return NULL;
+ }
+
+ /* ------------------------- *
+ * position the dimension
+ * ------------------------- */
+
+ Bnd_Box aBnd;
+ BRepBndLib::AddClose( aMainShape, aBnd );
+
+ // check whether the points share same edge
+ TopExp_Explorer anEdgeExp( aMainShape, TopAbs_EDGE, TopAbs_EDGE );
+ for ( ; anEdgeExp.More(); anEdgeExp.Next() )
+ {
+ TopoDS_Vertex anEdgeV1;
+ TopoDS_Vertex anEdgeV2;
+ TopExp::Vertices( TopoDS::Edge( anEdgeExp.Current() ), anEdgeV1, anEdgeV2 );
+ gp_Pnt anEdgePnt1 = BRep_Tool::Pnt( anEdgeV1 );
+ gp_Pnt anEdgePnt2 = BRep_Tool::Pnt( anEdgeV2 );
+
+ if ( aPnt1.Distance( anEdgePnt1 ) <= Precision::Confusion() )
{
- break;
+ if ( aPnt2.Distance( anEdgePnt2 ) <= Precision::Confusion() )
+ {
+ break;
+ }
+ }
+
+ if ( aPnt2.Distance( anEdgePnt1 ) <= Precision::Confusion() )
+ {
+ if ( aPnt1.Distance( anEdgePnt2 ) <= Precision::Confusion() )
+ {
+ break;
+ }
}
}
- gp_Pnt aPnt3 = aPnt2.Translated( aUnitVecs[aUnitVecIt] );
+ gp_Vec aFaceN1( gp::Origin(), gp::Origin() );
+ gp_Vec aFaceN2( gp::Origin(), gp::Origin() );
+ gp_Vec aFaceS1( gp::Origin(), gp::Origin() );
+ gp_Vec aFaceS2( gp::Origin(), gp::Origin() );
- GC_MakePlane aMkPlane( aPnt1, aPnt2, aPnt3 );
- Handle(Geom_Plane) aPlane = aMkPlane.Value();
+ // have shared edge
+ if ( anEdgeExp.More() )
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge( anEdgeExp.Current() );
+ TopTools_IndexedDataMapOfShapeListOfShape aRelationMap;
+ TopExp::MapShapesAndAncestors( aMainShape, TopAbs_EDGE, TopAbs_FACE, aRelationMap );
+ const TopTools_ListOfShape& aRelatedFaces = aRelationMap.FindFromKey( anEdge );
- // check whether it is possible to compute valid dimension
- Handle(AIS_LengthDimension) aDimension = new AIS_LengthDimension ( aFirstVertex, aSecondVertex, aPlane->Pln() );
+ gp_Pnt aMiddlePnt = gp_Pnt( ( aPnt1.XYZ() + aPnt2.XYZ() ) * 0.5 );
+
+ TopTools_ListIteratorOfListOfShape aFaceIt( aRelatedFaces );
+
+ // get face side directions
+ if ( aFaceIt.More() )
+ {
+ TopoDS_Face aFace = TopoDS::Face( aFaceIt.Value() );
+
+ gp_Dir aSideDir;
+ if ( GetFaceSide( aFace, anEdge, aSideDir ) )
+ {
+ aFaceS1 = aSideDir;
+ }
+
+ Handle(Geom_Surface) aSurface = BRep_Tool::Surface( aFace );
+
+ Standard_Real aU = 0.0, aV = 0.0;
+ GeomLib_Tool::Parameters( aSurface, aMiddlePnt, Precision::Confusion(), aU, aV );
+
+ gp_Dir aNorm;
+ if ( GeomLib::NormEstim( aSurface, gp_Pnt2d( aU, aV ), Precision::Confusion(), aNorm ) <= 1 )
+ {
+ aFaceN1 = aFace.Orientation() == TopAbs_REVERSED ? -aNorm : aNorm;
+ }
+
+ aFaceIt.Next();
+ }
+
+ if ( aFaceIt.More() )
+ {
+ TopoDS_Face aFace = TopoDS::Face( aFaceIt.Value() );
+
+ gp_Dir aSideDir;
+ if ( GetFaceSide( aFace, anEdge, aSideDir ) )
+ {
+ aFaceS2 = aSideDir;
+ }
+
+ Handle(Geom_Surface) aSurface = BRep_Tool::Surface( aFace );
+
+ Standard_Real aU = 0.0, aV = 0.0;
+ GeomLib_Tool::Parameters( aSurface, aMiddlePnt, Precision::Confusion(), aU, aV );
+
+ gp_Dir aNorm;
+ if ( GeomLib::NormEstim( aSurface, gp_Pnt2d( aU, aV ), Precision::Confusion(), aNorm ) <= 1 )
+ {
+ aFaceN2 = aFace.Orientation() == TopAbs_REVERSED ? -aNorm : aNorm;
+ }
+ }
+ }
+
+ gp_Pln aPln;
+ PositionLength( aBnd, aFaceN1, aFaceN2, aFaceS1, aFaceS2, aPnt1, aPnt2, aPln );
+
+ /* --------------------------------------------------------- *
+ * construct the dimension for the best selected position
+ * --------------------------------------------------------- */
+
+ Handle(AIS_LengthDimension) aDimension = new AIS_LengthDimension( aPnt1, aPnt2, aPln );
+
+ aDimension->SetFlyout( Settings.DefaultFlyout );
if ( !aDimension->IsValid() )
{
@@ -227,7 +379,7 @@ Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthByPoints( cons
// purpose :
//=================================================================================
Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthByParallelEdges( const GEOM::GeomObjPtr& theEdge1,
- const GEOM::GeomObjPtr& theEdge2 )
+ const GEOM::GeomObjPtr& theEdge2 ) const
{
TopoDS_Shape aFirstSh;
if ( !GEOMBase::GetShape( theEdge1.operator ->(), aFirstSh ) )
@@ -258,6 +410,8 @@ Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthByParallelEdge
// check whether it is possible to compute valid dimension
Handle(AIS_LengthDimension) aDimension = new AIS_LengthDimension ( aFirstEdge, aSecondEdge, aPlane->Pln() );
+ aDimension->SetFlyout( Settings.DefaultFlyout );
+
if ( !aDimension->IsValid() )
{
return NULL;
@@ -270,23 +424,250 @@ Handle(AIS_LengthDimension) MeasureGUI_DimensionCreateTool::LengthByParallelEdge
// function : Diameter
// purpose :
//=================================================================================
-Handle(AIS_DiameterDimension) MeasureGUI_DimensionCreateTool::Diameter( const GEOM::GeomObjPtr& theShape )
+Handle(AIS_DiameterDimension) MeasureGUI_DimensionCreateTool::Diameter( const GEOM::GeomObjPtr& theMeasuredObj ) const
{
- TopoDS_Shape aShape;
- if ( !GEOMBase::GetShape( theShape.operator ->(), aShape ) )
+ /* ------------------------------------------------ *
+ * get the shape and its parent (if exist) *
+ * ------------------------------------------------ */
+
+ TopoDS_Shape aMeasuredShape;
+ TopoDS_Shape aMainShape;
+ if ( !GEOMBase::GetShape( theMeasuredObj.operator ->(), aMeasuredShape ) )
{
return NULL;
}
- if ( aShape.ShapeType() != TopAbs_EDGE &&
- aShape.ShapeType() != TopAbs_FACE &&
- aShape.ShapeType() != TopAbs_WIRE )
+ if ( !GEOMBase::GetShape( GetMainShape( theMeasuredObj ).get(), aMainShape ) )
{
return NULL;
}
- // check whether it is possible to compute dimension on the passed geometry
- Handle(AIS_DiameterDimension) aDimension = new AIS_DiameterDimension( aShape );
+ Bnd_Box aBnd;
+ BRepBndLib::AddClose( aMainShape, aBnd );
+
+ /* ------------------------------------------------ *
+ * get the dimension construction arguments *
+ * ------------------------------------------------ */
+
+ Handle(Geom_Circle) aCircle;
+
+ Standard_Real aPmin = 0, aPmax = 2 * M_PI;
+
+ gp_Vec aFaceN( gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(0.0, 0.0, 0.0) );
+
+ switch ( aMeasuredShape.ShapeType() )
+ {
+ case TopAbs_FACE:
+ {
+ TopoDS_Face aMeasuredFace = TopoDS::Face(aMeasuredShape);
+
+ BRepAdaptor_Surface aSurf( aMeasuredFace );
+
+ Standard_Real aVmin = aSurf.FirstVParameter();
+ Standard_Real aVmax = aSurf.LastVParameter();
+
+ // get arguments of closed sphere
+ if ( aSurf.GetType() == GeomAbs_Sphere )
+ {
+ if ( !aSurf.IsUClosed() || !aSurf.IsVClosed() )
+ {
+ return NULL;
+ }
+
+ // take circle in XOY plane from sphere
+ gp_Sphere aSphere = aSurf.Sphere();
+ gp_Ax2 anAx2 = gp_Ax2( aSphere.Location(), gp::DZ() );
+ aCircle = new Geom_Circle( anAx2, aSphere.Radius() );
+ break;
+ }
+
+
+ // get arguments of closed torus
+ if ( aSurf.GetType() == GeomAbs_Torus )
+ {
+ if ( !aSurf.IsUClosed() || !aSurf.IsVClosed() )
+ {
+ return NULL;
+ }
+
+ gp_Torus aTorus = aSurf.Torus();
+ gp_Ax2 anAx2 = aTorus.Position().Ax2();
+ aCircle = new Geom_Circle( anAx2, aTorus.MinorRadius() );
+ break;
+ }
+
+ // get arguments of closed cone
+ if ( aSurf.GetType() == GeomAbs_Cone )
+ {
+ if ( !aSurf.IsUClosed() || !aSurf.IsVClosed() )
+ {
+ return NULL;
+ }
+
+ gp_Cone aCone = aSurf.Cone();
+ gp_Ax2 anAx2 = aCone.Position().Ax2();
+ aCircle = new Geom_Circle( anAx2, aCone.RefRadius() );
+
+ aFaceN = aCone.SemiAngle() > 0.0
+ ? anAx2.Axis().Direction()
+ : -anAx2.Axis().Direction();
+ break;
+ }
+
+ // get arguments of closed/opened cylinder
+ if ( aSurf.GetType() == GeomAbs_Cylinder )
+ {
+ Handle(Geom_Curve) aCurve = aSurf.Surface().Surface()->VIso( (aVmax + aVmin) * 0.5 );
+
+ if ( aCurve->IsKind( STANDARD_TYPE( Geom_Circle ) ) )
+ {
+ aPmin = aSurf.FirstUParameter();
+ aPmax = aSurf.LastUParameter();
+ aCircle = Handle(Geom_Circle)::DownCast( aCurve );
+ }
+ else if ( aCurve->IsKind( STANDARD_TYPE( Geom_TrimmedCurve ) ) )
+ {
+ Handle(Geom_TrimmedCurve) aTrimmedCurve = Handle(Geom_TrimmedCurve)::DownCast( aCurve );
+ aPmin = aTrimmedCurve->FirstParameter();
+ aPmax = aTrimmedCurve->LastParameter();
+
+ aCircle = Handle(Geom_Circle)::DownCast( aTrimmedCurve );
+ }
+
+ break;
+ }
+
+ // face containing edge?
+ TopExp_Explorer anExp( aMeasuredShape, TopAbs_EDGE );
+ if ( !anExp.More() )
+ {
+ return NULL;
+ }
+
+ TopoDS_Shape anExpEdge = anExp.Current();
+ if ( anExpEdge.IsNull() )
+ {
+ return NULL;
+ }
+
+ // only a single edge is expected
+ anExp.Next();
+ if ( anExp.More() )
+ {
+ return NULL;
+ }
+
+ // do not break, go to edge checking
+ aMeasuredShape = anExpEdge;
+ }
+
+ case TopAbs_EDGE:
+ {
+ TopoDS_Edge aMeasureEdge = TopoDS::Edge( aMeasuredShape );
+
+ BRepAdaptor_Curve aCurve(aMeasureEdge);
+
+ if ( aCurve.GetType() != GeomAbs_Circle )
+ {
+ return NULL;
+ }
+
+ aPmin = aCurve.FirstParameter();
+ aPmax = aCurve.LastParameter();
+
+ aCircle = new Geom_Circle( aCurve.Circle() );
+
+ // check if there is an parent face containing the edge
+ TopTools_IndexedDataMapOfShapeListOfShape aShapeMap;
+ TopExp::MapShapesAndAncestors( aMainShape, TopAbs_EDGE, TopAbs_FACE, aShapeMap );
+ const TopTools_ListOfShape& aFaces = aShapeMap.FindFromKey( aMeasureEdge );
+
+ TopTools_ListIteratorOfListOfShape aFaceIt( aFaces );
+ for ( ; aFaceIt.More(); aFaceIt.Next() )
+ {
+ Handle(Geom_Surface) aSurface = BRep_Tool::Surface( TopoDS::Face( aFaceIt.Value() ) );
+
+ gp_Pnt aCircCenter = aCircle->Circ().Location();
+ Standard_Real aCircU = 0.0, aCircV = 0.0;
+ GeomLib_Tool::Parameters( aSurface, aCircCenter, Precision::Confusion(), aCircU, aCircV );
+
+ gp_Dir aNorm;
+ if ( GeomLib::NormEstim( aSurface, gp_Pnt2d( aCircU, aCircV ), Precision::Confusion(), aNorm ) > 1 )
+ {
+ break;
+ }
+
+ if ( aNorm.Angle( aCircle->Circ().Axis().Direction() ) > M_PI * 0.25 )
+ {
+ continue;
+ }
+
+ aFaceN = gp_Vec( aNorm );
+ }
+ }
+ break;
+ }
+
+ if ( aCircle.IsNull() )
+ {
+ return NULL;
+ }
+
+ ElCLib::AdjustPeriodic( 0.0, M_PI * 2, Precision::PConfusion(), aPmin, aPmax );
+
+ /* ------------------------- *
+ * position the dimension
+ * ------------------------- */
+
+ gp_Pnt aPnt1;
+ gp_Pnt aPnt2;
+ gp_Pln aPln;
+
+ // diameter for closed circle
+ if ( Abs( ( aPmax - aPmin ) - M_PI * 2 ) <= Precision::PConfusion() )
+ {
+ PositionDiameter( aBnd, aFaceN, aCircle->Circ(), aPnt1, aPnt2, aPln );
+ }
+ // diameter for half-closed circle
+ else if ( Abs( aPmax - aPmin ) > M_PI )
+ {
+ Standard_Real anAnchor = aPmin + ( ( aPmax - aPmin ) - M_PI ) * 0.5;
+
+ PositionDiameter( aBnd, aFaceN, aCircle->Circ(), anAnchor, aPln );
+
+ aPnt1 = ElCLib::Value( anAnchor, aCircle->Circ() );
+ aPnt2 = ElCLib::Value( anAnchor + M_PI, aCircle->Circ() );
+ }
+ // diameter for less than half-closed circle
+ else
+ {
+ Standard_Real anAnchor = aPmin + ( aPmax - aPmin ) * 0.5;
+
+ PositionDiameter( aBnd, aFaceN, aCircle->Circ(), anAnchor, aPln );
+
+ aPnt1 = ElCLib::Value( anAnchor, aCircle->Circ() );
+ aPnt2 = ElCLib::Value( anAnchor + M_PI, aCircle->Circ() );
+ }
+
+ /* --------------------------------------------------------- *
+ * construct the dimension for the best selected position
+ * --------------------------------------------------------- */
+
+ gp_Pnt aCircP = aCircle->Circ().Location();
+ gp_Dir aCircN = aCircle->Circ().Axis().Direction();
+ gp_Dir aCircX = gce_MakeDir( aPnt1, aPnt2 );
+ Standard_Real aCircR = aCircle->Circ().Radius();
+
+ // construct closed circle as base for the diameter dimension
+ gp_Circ aRuledCirc = gce_MakeCirc( gp_Ax2( aCircP, aCircN, aCircX ), aCircR );
+
+ Handle(AIS_DiameterDimension) aDimension = new AIS_DiameterDimension( aRuledCirc, aPln );
+
+ // if flyout is extended in tangent direction to circle, the default flyout value is used
+ // if flyout is extended in plane of circle, the zero flyout value is choosen initially
+ Standard_Real aFlyout = aCircN.IsParallel( aPln.Axis().Direction(), Precision::Angular() ) ? 0.0 : Settings.DefaultFlyout;
+
+ aDimension->SetFlyout(aFlyout);
if ( !aDimension->IsValid() )
{
@@ -301,7 +682,7 @@ Handle(AIS_DiameterDimension) MeasureGUI_DimensionCreateTool::Diameter( const GE
// purpose :
//=================================================================================
Handle(AIS_AngleDimension) MeasureGUI_DimensionCreateTool::AngleByTwoEdges( const GEOM::GeomObjPtr& theEdge1,
- const GEOM::GeomObjPtr& theEdge2 )
+ const GEOM::GeomObjPtr& theEdge2 ) const
{
/* --------------------------------------------------- */
/* get construction and parent shapes */
@@ -358,6 +739,8 @@ Handle(AIS_AngleDimension) MeasureGUI_DimensionCreateTool::AngleByTwoEdges( cons
aDimension = new AIS_AngleDimension( aSecondPoint, aCenterPoint, aFirstPoint );
}
+ aDimension->SetFlyout( Settings.DefaultFlyout );
+
return aDimension;
}
@@ -367,7 +750,7 @@ Handle(AIS_AngleDimension) MeasureGUI_DimensionCreateTool::AngleByTwoEdges( cons
//=================================================================================
Handle(AIS_AngleDimension) MeasureGUI_DimensionCreateTool::AngleByThreePoints( const GEOM::GeomObjPtr& thePoint1,
const GEOM::GeomObjPtr& thePoint2,
- const GEOM::GeomObjPtr& thePoint3 )
+ const GEOM::GeomObjPtr& thePoint3 ) const
{
TopoDS_Shape aFirstSh;
if ( !GEOMBase::GetShape( thePoint1.operator ->(), aFirstSh ) )
@@ -407,73 +790,248 @@ Handle(AIS_AngleDimension) MeasureGUI_DimensionCreateTool::AngleByThreePoints( c
}
//=================================================================================
-// function : ChooseLengthFlyoutsFromShape
-// purpose :
+// function : PositionLength
+// purpose : The method provides preliminary positioning algorithm for
+// for length dimensions measuring the length between two points.
+// Parameters:
+// theBnd [in] - the bounding box of the main shape
+// theFaceN1 [in] - the normal to a first face of edge length (if any)
+// theFaceN2 [in] - the normal to a second face of edge length (if any)
+// theFaceS1 [in] - the side vector from a first face of edge length (if any)
+// theFaceS2 [in] - the side vector from a second face of edge length (if any)
+// thePnt1 [in] - the first measured point
+// thePnt2 [in] - the last measured point
+// The method selects flyout plane to best match the current
+// view projection. If edge length is constructed, then the flyout
+// can go in line with sides of faces, normal to the faces, or
+// aligned to XOY, YOZ, ZOX planes.
//=================================================================================
-void MeasureGUI_DimensionCreateTool::ChooseLengthFlyoutsFromShape( TColgp_SequenceOfDir& theDirs,
- const TopoDS_Vertex& theVertex1,
- const TopoDS_Vertex& theVertex2,
- const TopoDS_Shape& theShape )
+void MeasureGUI_DimensionCreateTool::PositionLength( const Bnd_Box& theBnd,
+ const gp_Vec& theFaceN1,
+ const gp_Vec& theFaceN2,
+ const gp_Vec& theFaceS1,
+ const gp_Vec& theFaceS2,
+ const gp_Pnt& thePnt1,
+ const gp_Pnt& thePnt2,
+ gp_Pln& thePln ) const
{
-}
-
-//=================================================================================
-// function : ChooseLengthFlyoutsFromShape
-// purpose :
-//=================================================================================
-void MeasureGUI_DimensionCreateTool::ChooseLengthFlyoutsFromShape( TColgp_SequenceOfDir& theDirs,
- const TopoDS_Edge& theEdge,
- const TopoDS_Shape& theShape )
-{
- TopTools_IndexedDataMapOfShapeListOfShape aRelationMap;
- TopExp::MapShapesAndAncestors( theShape, TopAbs_EDGE, TopAbs_FACE, aRelationMap );
- const TopTools_ListOfShape& aRelatedFaces = aRelationMap.FindFromKey( theEdge );
-
- // get face side directions
- gp_Dir aSideDir;
- if ( aRelatedFaces.Extent() > 0 && GetFaceSide( TopoDS::Face( aRelatedFaces.First() ), theEdge, aSideDir ) )
- {
- theDirs.Append( aSideDir );
- }
- if ( aRelatedFaces.Extent() > 1 && GetFaceSide( TopoDS::Face( aRelatedFaces.Last() ), theEdge, aSideDir ) )
- {
- theDirs.Append( aSideDir );
- }
+ Standard_Boolean isFace1 = theFaceN1.Magnitude() > Precision::Confusion();
+ Standard_Boolean isFace2 = theFaceN2.Magnitude() > Precision::Confusion();
+ gp_Vec anAverageN( gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(0.0, 0.0, 0.0) );
// get average direction in case of two non-sharp angled faces
- if ( theDirs.Length() == 2 )
+ if ( isFace1 && isFace2 )
{
- const gp_Dir& aDir1 = theDirs.First();
- const gp_Dir& aDir2 = theDirs.Last();
- Standard_Boolean isSame = aDir1.IsParallel( aDir2, Precision::Angular() );
+ Standard_Boolean isSame = theFaceN1.IsParallel( theFaceN2, Precision::Angular() );
if ( !isSame )
{
- gp_Dir aReferenceDir = aDir1 ^ aDir2;
+ gp_Dir aReferenceDir = theFaceN1 ^ theFaceN2;
// compute angle between face sides [0 - 2PI]
- Standard_Real aDirAngle = aDir1.AngleWithRef( aDir2, aReferenceDir );
+ Standard_Real aDirAngle = theFaceN1.AngleWithRef( theFaceN2, aReferenceDir );
if ( aDirAngle < 0 )
{
aDirAngle = ( M_PI * 2.0 ) - aDirAngle;
}
- // non-sharp angle, use averaged direction
+ // non-sharp angle, use averaged directio
+ if ( aDirAngle > M_PI * 0.5 )
+ {
+ anAverageN = theFaceN1 + theFaceN2;
+ }
+
if ( aDirAngle > M_PI )
{
- theDirs.Clear();
- theDirs.Append( aDir1.Rotated( gp_Ax1( gp::Origin(), aReferenceDir ), aDirAngle * 0.5 ) );
+ isFace1 = Standard_False;
+ isFace2 = Standard_False;
}
}
}
+
+ Standard_Boolean isAverage = anAverageN.Magnitude() > Precision::Confusion();
+
+ SeqOfDirs aFlyoutDirs;
+ if ( isFace1 )
+ {
+ aFlyoutDirs.Append( theFaceN1 );
+ aFlyoutDirs.Append( theFaceS1 );
+ }
+ if ( isFace2 )
+ {
+ aFlyoutDirs.Append( theFaceN2 );
+ aFlyoutDirs.Append( theFaceS2 );
+ }
+ if ( isAverage )
+ {
+ aFlyoutDirs.Append( anAverageN );
+ }
+
+ ChooseLengthFlyoutsFromBnd( aFlyoutDirs, thePnt1, thePnt2, theBnd );
+
+ if ( aFlyoutDirs.IsEmpty() )
+ {
+ return;
+ }
+
+ gp_Dir aPointDir = gce_MakeDir( thePnt1, thePnt2 );
+
+ // make planes for dimension presentation according to flyout directions
+ SeqOfPlanes aSeqOfPlanes;
+ for ( Standard_Integer aFlyoutIt = 1; aFlyoutIt <= aFlyoutDirs.Length(); ++aFlyoutIt )
+ {
+ gp_Pln aPlane( thePnt1, aPointDir ^ aFlyoutDirs.Value( aFlyoutIt ) );
+ aSeqOfPlanes.Append( aPlane );
+ }
+
+ Handle(V3d_View) aView = Settings.ActiveView;
+
+ thePln = !aView.IsNull()
+ ? SelectPlaneForProjection( aSeqOfPlanes, aView )
+ : aSeqOfPlanes.First();
+}
+
+//=================================================================================
+// function : PositionDiameter
+// purpose : The method provides preliminary positioning algorithm for
+// for diameter dimensions measuring the circle.
+// Parameters:
+// theBnd [in] - the bounding box of the shape
+// theFaceN [in] - the circle face normal (can be void)
+// theCirc [in] - the measured circle
+// thePnt1 [out] - first dimension point
+// thePnt2 [out] - second dimension point
+// thePln [out] - dimension flyout plane
+// The method selects points on the circle for diameter dimension and
+// flyout plane to best match the current view projection (if any)
+// The points are aligned to XOY, YOZ, ZOX planes.
+// The flyout takes into account bounding box of main shape of face normal
+// vector. The flyouts tangetial to the circle plane are directed in
+// accordance with the face normal (if not-null), otherwise the flyouts
+// are turned to direct to the closest border of bounding box.
+//=================================================================================
+void MeasureGUI_DimensionCreateTool::PositionDiameter( const Bnd_Box& theBnd,
+ const gp_Vec& theFaceN,
+ const gp_Circ& theCirc,
+ gp_Pnt& thePnt1,
+ gp_Pnt& thePnt2,
+ gp_Pln& thePln ) const
+{
+ // plane associated with custom data
+ struct PlaneAndSegment
+ {
+ PlaneAndSegment() {}
+ PlaneAndSegment(const gp_Pln& thePlane, const Segment& theSegment) : pln(thePlane), seg(theSegment) {}
+ operator gp_Pln () const { return pln; }
+ operator Segment () const { return seg; }
+ gp_Pln pln;
+ Segment seg;
+ };
+ typedef NCollection_Sequence SeqOfPlnsAndSegments;
+
+ // select list of measured segments aligned to projection planes
+ SeqOfDirs aProjectionDirs;
+ aProjectionDirs.Append( gp::DX() );
+ aProjectionDirs.Append( gp::DY() );
+ aProjectionDirs.Append( gp::DZ() );
+
+ SeqOfSegments aMeasureSegments = GetInPlaneSegments( theCirc, aProjectionDirs );
+
+ SeqOfPlnsAndSegments aSelectedPlanes;
+
+ // select in-circle-plane direction for flyout closest to border of bounding box
+ for ( Standard_Integer aSegmentIt = 1; aSegmentIt <= aMeasureSegments.Length(); ++aSegmentIt )
+ {
+ const Segment& aSegment = aMeasureSegments.Value(aSegmentIt);
+
+ Standard_Real anAnchor = ElCLib::Parameter( theCirc, aSegment.First );
+
+ gp_Pln aSelectedPlane;
+
+ PositionDiameter( theBnd, theFaceN, theCirc, anAnchor, aSelectedPlane );
+
+ aSelectedPlanes.Append( PlaneAndSegment( aSelectedPlane, aSegment ) );
+ }
+
+ Handle(V3d_View) aView = Settings.ActiveView;
+
+ PlaneAndSegment aChoosenParams = !aView.IsNull()
+ ? SelectPlaneForProjection( aSelectedPlanes, aView )
+ : aSelectedPlanes.First();
+
+ thePnt1 = ((Segment)aChoosenParams).First;
+ thePnt2 = ((Segment)aChoosenParams).Last;
+ thePln = ((gp_Pln)aChoosenParams);
+}
+
+//=================================================================================
+// function : PositionDiameter
+// purpose : The method provides preliminary positioning algorithm for
+// for diameter dimensions measuring the circle. The diameter
+// dimension is bound at anchor point on the circle.
+// Parameters:
+// theBnd [in] the bounding box of the shape
+// theFaceN [in] - the circle face normal (can be void)
+// theCirc [in] - the measured circle
+// theAnchorAt [in] - the anchoring parameter
+// thePln [out] - dimension flyout plane
+// The method selects flyout plane to best match the current
+// view projection. The flyout plane can be parallel to circle,
+// or tangent to it.
+//=================================================================================
+void MeasureGUI_DimensionCreateTool::PositionDiameter( const Bnd_Box& theBnd,
+ const gp_Vec& theFaceN,
+ const gp_Circ& theCirc,
+ const Standard_Real& theAnchorAt,
+ gp_Pln& thePln ) const
+{
+ gp_Dir aCircN = theCirc.Axis().Direction();
+ gp_Pnt aCircP = theCirc.Location();
+
+ // select tangent direction for flyout closest to border of bounding box
+ gp_Dir aSelectedTanDir;
+ if ( theFaceN.Magnitude() < Precision::Confusion() )
+ {
+ SeqOfDirs aTangentDirs;
+ aTangentDirs.Append( aCircN );
+ aTangentDirs.Append( -aCircN );
+ aSelectedTanDir = ChooseDirFromBnd( aTangentDirs, aCircP, theBnd );
+ }
+ else
+ {
+ aSelectedTanDir = gp_Dir( theFaceN );
+ }
+
+ gp_Pnt aPnt1 = ElCLib::Value( theAnchorAt, theCirc );
+ gp_Pnt aPnt2 = ElCLib::Value( theAnchorAt + M_PI, theCirc );
+
+ gp_Dir aSegmentDir = gce_MakeDir( aPnt1, aPnt2 );
+
+ SeqOfDirs aSegmentDirs;
+ aSegmentDirs.Append( aCircN ^ aSegmentDir );
+ aSegmentDirs.Append( -aCircN ^ aSegmentDir );
+ gp_Dir aSelectedSegDir = ChooseDirFromBnd( aSegmentDirs, aCircP, theBnd );
+
+ gp_Pln aTangentFlyout( aCircP, aSegmentDir ^ aSelectedTanDir );
+ gp_Pln aCoplanarFlyout( aCircP, aSegmentDir ^ aSelectedSegDir );
+
+ SeqOfPlanes aSelectedPlanes;
+ aSelectedPlanes.Append( aTangentFlyout );
+ aSelectedPlanes.Append( aCoplanarFlyout );
+
+ Handle(V3d_View) aView = Settings.ActiveView;
+
+ thePln = !aView.IsNull()
+ ? SelectPlaneForProjection( aSelectedPlanes, aView )
+ : aSelectedPlanes.First();
}
//=================================================================================
// function : ChooseLengthFlyoutsFromBnd
// purpose :
//=================================================================================
-void MeasureGUI_DimensionCreateTool::ChooseLengthFlyoutsFromBnd( TColgp_SequenceOfDir& theDirs,
+void MeasureGUI_DimensionCreateTool::ChooseLengthFlyoutsFromBnd( SeqOfDirs& theDirs,
const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
- const Bnd_Box& theBnd )
+ const Bnd_Box& theBnd ) const
{
// compose a list of axis-aligned planes for lying-in flyouts
NCollection_Sequence anAAPlanes;
@@ -526,12 +1084,54 @@ void MeasureGUI_DimensionCreateTool::ChooseLengthFlyoutsFromBnd( TColgp_Sequence
}
}
+//=================================================================================
+// function : ChooseDirFromBnd
+// purpose : The method chooses the best direction from the passed list of
+// directions, which is closest to the bounding box border.
+// Parameters:
+// theCandidates [in] the list of candidate directions
+// thePos [in] the position from where the directions are traced
+// theBnd [in] the bounding box of main shape
+//=================================================================================
+gp_Dir MeasureGUI_DimensionCreateTool::ChooseDirFromBnd( const SeqOfDirs& theCandidates,
+ const gp_Pnt& thePos,
+ const Bnd_Box& theBnd ) const
+{
+ gp_Dir aBestDir;
+
+ Standard_Real aBestDistance = RealLast();
+
+ SeqOfDirs::Iterator anIt( theCandidates );
+ for ( ; anIt.More(); anIt.Next() )
+ {
+ const gp_Dir& aDir = anIt.Value();
+
+ gp_Ax3 aFlyoutSpace( thePos, aDir );
+
+ gp_Trsf aRelativeTransform;
+ aRelativeTransform.SetTransformation( gp_Ax3(), aFlyoutSpace );
+ Bnd_Box aRelativeBounds = theBnd.Transformed( aRelativeTransform );
+
+ Standard_Real aXmin, aXmax, aYmin, aYmax, aZmin, aZmax;
+ aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+
+ if ( aYmax < aBestDistance )
+ {
+ aBestDir = aDir;
+ aBestDistance = aYmax;
+ }
+ }
+
+ return aBestDir;
+}
+
//=================================================================================
// function : SelectPlaneForProjection
// purpose : Select best matching plane in current view projection
//=================================================================================
-gp_Pln MeasureGUI_DimensionCreateTool::SelectPlaneForProjection( const NCollection_Sequence& thePlanes,
- const Handle(V3d_View)& theView )
+template
+TPlane MeasureGUI_DimensionCreateTool::SelectPlaneForProjection( const NCollection_Sequence& thePlanes,
+ const Handle(V3d_View)& theView ) const
{
Quantity_Parameter U[3];
Quantity_Parameter N[3];
@@ -541,15 +1141,15 @@ gp_Pln MeasureGUI_DimensionCreateTool::SelectPlaneForProjection( const NCollecti
gp_Dir aViewN( (Standard_Real)N[0], (Standard_Real)N[1], (Standard_Real)N[2] );
gp_Dir aViewU( (Standard_Real)U[0], (Standard_Real)U[1], (Standard_Real)U[2] );
- gp_Pln aBestPlane = thePlanes.First();
+ TPlane aBestPlane = thePlanes.First();
Standard_Real aBestDotProduct = RealFirst();
for ( Standard_Integer aPlnIt = 1; aPlnIt <= thePlanes.Length(); ++aPlnIt )
{
- const gp_Pln& aPlane = thePlanes.Value( aPlnIt );
+ const TPlane& aPlane = thePlanes.Value( aPlnIt );
- Standard_Real aDotProduct = Abs( aPlane.Axis().Direction() * aViewN );
+ Standard_Real aDotProduct = Abs( ((gp_Pln)aPlane).Axis().Direction() * aViewN );
// preferred plane is "view parallel"
if ( aDotProduct <= aBestDotProduct )
@@ -569,7 +1169,7 @@ gp_Pln MeasureGUI_DimensionCreateTool::SelectPlaneForProjection( const NCollecti
// function : GetMainShape
// purpose :
//=================================================================================
-GEOM::GeomObjPtr MeasureGUI_DimensionCreateTool::GetMainShape( const GEOM::GeomObjPtr& theShape )
+GEOM::GeomObjPtr MeasureGUI_DimensionCreateTool::GetMainShape( const GEOM::GeomObjPtr& theShape ) const
{
// iterate over top-level objects to search for main shape
GEOM::GeomObjPtr aMainShapeIt = theShape;
@@ -584,7 +1184,7 @@ GEOM::GeomObjPtr MeasureGUI_DimensionCreateTool::GetMainShape( const GEOM::GeomO
// function : GetFaceSide
// purpose :
//=================================================================================
-bool MeasureGUI_DimensionCreateTool::GetFaceSide( const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, gp_Dir& theDir )
+bool MeasureGUI_DimensionCreateTool::GetFaceSide( const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, gp_Dir& theDir ) const
{
// get correctly oriented edge from main shape
TopoDS_Edge anEdgeFromFace;
@@ -648,3 +1248,44 @@ bool MeasureGUI_DimensionCreateTool::GetFaceSide( const TopoDS_Face& theFace, co
theDir = gp_Dir( aTangent ) ^ aNorm;
return true;
}
+
+//=================================================================================
+// function : GetInPlaneSegments
+// purpose : The method finds segments crossing the passed circle,
+// which lie in the passed planes.
+// Parameters:
+// theCirc [in] the circle to be crossed.
+// thePlanes [in] the projection planes crossing the circle.
+//=================================================================================
+MeasureGUI_DimensionCreateTool::SeqOfSegments
+ MeasureGUI_DimensionCreateTool::GetInPlaneSegments( const gp_Circ& theCirc,
+ const SeqOfDirs& thePlanes ) const
+{
+ SeqOfSegments aResult;
+
+ gp_Pnt aCircP = theCirc.Location();
+ gp_Dir aCircN = theCirc.Axis().Direction();
+ Standard_Real aCircR = theCirc.Radius();
+
+ SeqOfDirs::Iterator anIt( thePlanes );
+ for ( ; anIt.More(); anIt.Next() )
+ {
+ const gp_Dir& aDir = anIt.Value();
+
+ if ( aDir.IsParallel( aCircN, Precision::Angular() ) )
+ {
+ continue;
+ }
+
+ gp_Dir aIntDir = aDir ^ aCircN;
+
+ gp_Pnt aPnt1 = gp_Pnt( aCircP.XYZ() - aIntDir.XYZ() * aCircR );
+ gp_Pnt aPnt2 = gp_Pnt( aCircP.XYZ() + aIntDir.XYZ() * aCircR );
+ Segment aSegment;
+ aSegment.First = aPnt1;
+ aSegment.Last = aPnt2;
+ aResult.Append( aSegment );
+ }
+
+ return aResult;
+}
diff --git a/src/MeasureGUI/MeasureGUI_DimensionCreateTool.h b/src/MeasureGUI/MeasureGUI_DimensionCreateTool.h
index 978aaa915..8a396786c 100644
--- a/src/MeasureGUI/MeasureGUI_DimensionCreateTool.h
+++ b/src/MeasureGUI/MeasureGUI_DimensionCreateTool.h
@@ -47,60 +47,96 @@
//=================================================================================
class MeasureGUI_DimensionCreateTool
{
+ struct Segment
+ {
+ gp_Pnt First;
+ gp_Pnt Last;
+ };
+ typedef NCollection_Sequence SeqOfDirs;
+ typedef NCollection_Sequence SeqOfPlanes;
+ typedef NCollection_Sequence SeqOfSegments;
+
public:
- MeasureGUI_DimensionCreateTool( GeometryGUI* );
+ MeasureGUI_DimensionCreateTool();
+
+ struct
+ {
+ Standard_Real DefaultFlyout;
+ Handle(V3d_View) ActiveView;
+ } Settings;
/* construction methods */
public:
- Handle(AIS_LengthDimension) LengthOnEdge( const GEOM::GeomObjPtr& );
+ Handle(AIS_LengthDimension) LengthOnEdge( const GEOM::GeomObjPtr& ) const;
Handle(AIS_LengthDimension) LengthByPoints( const GEOM::GeomObjPtr&,
- const GEOM::GeomObjPtr& );
+ const GEOM::GeomObjPtr& ) const;
Handle(AIS_LengthDimension) LengthByParallelEdges( const GEOM::GeomObjPtr&,
- const GEOM::GeomObjPtr& );
+ const GEOM::GeomObjPtr& ) const;
- Handle(AIS_DiameterDimension) Diameter( const GEOM::GeomObjPtr& );
+ Handle(AIS_DiameterDimension) Diameter( const GEOM::GeomObjPtr& ) const;
Handle(AIS_AngleDimension) AngleByTwoEdges( const GEOM::GeomObjPtr&,
- const GEOM::GeomObjPtr& );
+ const GEOM::GeomObjPtr& ) const;
Handle(AIS_AngleDimension) AngleByThreePoints( const GEOM::GeomObjPtr&,
const GEOM::GeomObjPtr&,
- const GEOM::GeomObjPtr& );
+ const GEOM::GeomObjPtr& ) const;
+
/* selecting flyout direction for length dimensions */
protected:
- void ChooseLengthFlyoutsFromShape( TColgp_SequenceOfDir&,
- const TopoDS_Vertex&,
- const TopoDS_Vertex&,
- const TopoDS_Shape& );
+ void ChooseLengthFlyoutsFromBnd( SeqOfDirs&,
+ const gp_Pnt&,
+ const gp_Pnt&,
+ const Bnd_Box& ) const;
- void ChooseLengthFlyoutsFromShape( TColgp_SequenceOfDir&,
- const TopoDS_Edge&,
- const TopoDS_Shape& );
-
- void ChooseLengthFlyoutsFromBnd( TColgp_SequenceOfDir&,
- const gp_Pnt&,
- const gp_Pnt&,
- const Bnd_Box& );
+ gp_Dir ChooseDirFromBnd( const SeqOfDirs&,
+ const gp_Pnt&,
+ const Bnd_Box& ) const;
/* selecting best flyout direction taking into account view projection */
protected:
- gp_Pln SelectPlaneForProjection( const NCollection_Sequence&,
- const Handle(V3d_View)& );
+ template
+ TPlane SelectPlaneForProjection( const NCollection_Sequence&,
+ const Handle(V3d_View)& ) const;
+
+/* positioning */
+protected:
+
+ void PositionLength( const Bnd_Box&,
+ const gp_Vec&,
+ const gp_Vec&,
+ const gp_Vec&,
+ const gp_Vec&,
+ const gp_Pnt&,
+ const gp_Pnt&,
+ gp_Pln& ) const;
+
+ void PositionDiameter( const Bnd_Box&,
+ const gp_Vec&,
+ const gp_Circ&,
+ gp_Pnt&,
+ gp_Pnt&,
+ gp_Pln& ) const;
+
+ void PositionDiameter( const Bnd_Box&,
+ const gp_Vec&,
+ const gp_Circ&,
+ const Standard_Real&,
+ gp_Pln& ) const;
/* utility */
protected:
- GEOM::GeomObjPtr GetMainShape( const GEOM::GeomObjPtr& );
+ GEOM::GeomObjPtr GetMainShape( const GEOM::GeomObjPtr& ) const;
bool GetFaceSide( const TopoDS_Face&,
const TopoDS_Edge&,
- gp_Dir& );
-
-private:
- GeometryGUI* myGeomGUI;
+ gp_Dir& ) const;
+ SeqOfSegments GetInPlaneSegments( const gp_Circ&,
+ const SeqOfDirs& ) const;
};
#endif
diff --git a/src/MeasureGUI/MeasureGUI_DimensionInteractor.cxx b/src/MeasureGUI/MeasureGUI_DimensionInteractor.cxx
index 48b9dbda4..56b921a20 100644
--- a/src/MeasureGUI/MeasureGUI_DimensionInteractor.cxx
+++ b/src/MeasureGUI/MeasureGUI_DimensionInteractor.cxx
@@ -518,8 +518,9 @@ void MeasureGUI_DimensionInteractor::MoveText( const Handle(V3d_View)& theView,
const gp_Dir& aPlaneN = aPlane.Axis().Direction();
- Prs3d_DimensionTextHorizontalPosition aHPos = myInteractedIO->DimensionAspect()->TextHorizontalPosition();
- Prs3d_DimensionTextVerticalPosition aVPos = myInteractedIO->DimensionAspect()->TextVerticalPosition();
+ Prs3d_DimensionTextHorizontalPosition aHPos = myInteractedIO->DimensionAspect()->TextHorizontalPosition();
+ Prs3d_DimensionTextVerticalPosition aVPos = myInteractedIO->DimensionAspect()->TextVerticalPosition();
+ Prs3d_DimensionArrowOrientation aArrPos = myInteractedIO->DimensionAspect()->ArrowOrientation();
Standard_Real aHeight = myInteractedIO->DimensionAspect()->TextAspect()->Height() * 0.5;
@@ -563,15 +564,18 @@ void MeasureGUI_DimensionInteractor::MoveText( const Handle(V3d_View)& theView,
if ( aPosX < 0.0 )
{
- aHPos = Prs3d_DTHP_Left;
+ aHPos = Prs3d_DTHP_Left;
+ aArrPos = Prs3d_DAO_External;
}
else if ( aPosX > aFirstPoint.Distance( aSecondPoint ) )
{
- aHPos = Prs3d_DTHP_Right;
+ aHPos = Prs3d_DTHP_Right;
+ aArrPos = Prs3d_DAO_External;
}
else
{
- aHPos = Prs3d_DTHP_Center;
+ aHPos = Prs3d_DTHP_Center;
+ aArrPos = Prs3d_DAO_Fit;
}
if ( aPosY > aHeight )
@@ -636,16 +640,19 @@ void MeasureGUI_DimensionInteractor::MoveText( const Handle(V3d_View)& theView,
if ( aPointAngle < -aDirAngle * 0.5 ) // outside of second dir
{
aHPos = Prs3d_DTHP_Left;
+ aArrPos = Prs3d_DAO_External;
aPosY = Abs( aPointVec.Dot( aFirstDir ) ) - Abs( myInteractedIO->GetFlyout() );
}
else if ( aPointAngle > aDirAngle * 0.5 ) // outside of first dir
{
aHPos = Prs3d_DTHP_Right;
+ aArrPos = Prs3d_DAO_External;
aPosY = Abs( aPointVec.Dot( aSecondDir ) ) - Abs( myInteractedIO->GetFlyout() );
}
else // between first and second direction
{
aHPos = Prs3d_DTHP_Center;
+ aArrPos = Prs3d_DAO_Fit;
aPosY = Abs( aPointVec.Magnitude() ) - Abs( myInteractedIO->GetFlyout() );
}
@@ -665,6 +672,7 @@ void MeasureGUI_DimensionInteractor::MoveText( const Handle(V3d_View)& theView,
myInteractedIO->DimensionAspect()->SetTextVerticalPosition( aVPos );
myInteractedIO->DimensionAspect()->SetTextHorizontalPosition( aHPos );
+ myInteractedIO->DimensionAspect()->SetArrowOrientation( aArrPos );
myInteractedIO->SetToUpdate();
myViewer->getAISContext()->Redisplay( myInteractedIO );
diff --git a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx
index 62b43b4e2..fb739349e 100644
--- a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx
+++ b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx
@@ -121,6 +121,9 @@ MeasureGUI_ManageDimensionsDlg::MeasureGUI_ManageDimensionsDlg( GeometryGUI* the
connect( buttonApply(), SIGNAL( clicked() ), SLOT( ClickOnApply() ) );
connect( this, SIGNAL( finished( int ) ), SLOT( OnFinish() ) );
+
+ connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
+ connect( myGeomGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) );
myDimensionInteractor = new MeasureGUI_DimensionInteractor( theGUI, theParent ),
@@ -130,6 +133,8 @@ MeasureGUI_ManageDimensionsDlg::MeasureGUI_ManageDimensionsDlg( GeometryGUI* the
{
myObjectSelector->PushButton1->click();
}
+
+ setHelpFileName("managing_dimensions_page.html");
}
//=================================================================================
@@ -151,7 +156,7 @@ void MeasureGUI_ManageDimensionsDlg::StartSelection( const Selection theSelectio
myCurrentSelection = theSelection;
- if ( theSelection == Selection_Object && WarnUnsaved() )
+ if ( theSelection == Selection_Object && AllowedToCancelChanges() )
{
/* ----------------------------------------------- *
* selection of object *
@@ -703,7 +708,7 @@ void MeasureGUI_ManageDimensionsDlg::ClickOnOk()
//=================================================================================
void MeasureGUI_ManageDimensionsDlg::ClickOnCancel()
{
- if ( !WarnUnsaved() )
+ if ( !AllowedToCancelChanges() )
{
return;
}
@@ -781,6 +786,70 @@ void MeasureGUI_ManageDimensionsDlg::OnFinish()
redisplay( myEditObject.get() );
}
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void MeasureGUI_ManageDimensionsDlg::enterEvent( QEvent* )
+{
+ if ( !mainFrame()->GroupConstructors->isEnabled() )
+ {
+ OnActivateThisDialog();
+ }
+}
+
+//=================================================================================
+// function : OnActivateThisDialog
+// purpose :
+//=================================================================================
+void MeasureGUI_ManageDimensionsDlg::OnActivateThisDialog()
+{
+ disconnect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
+ GEOMBase_Skeleton::ActivateThisDialog();
+ connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
+
+ SelectionIntoArgument( Selection_Object );
+
+ if ( myEditObject.isNull() )
+ {
+ myObjectSelector->PushButton1->click();
+ }
+}
+
+//=================================================================================
+// function : OnDeactivateThisDialog
+// purpose :
+//=================================================================================
+void MeasureGUI_ManageDimensionsDlg::OnDeactivateThisDialog()
+{
+ if ( AllowedToSaveChanges() )
+ {
+ ClickOnApply();
+ }
+
+ if ( !myEditObject.isNull() )
+ {
+ SalomeApp_Study* aStudy = NULL;
+ SalomeApp_Application* anApp = myGeomGUI->getApp();
+ if ( anApp )
+ {
+ aStudy = dynamic_cast( anApp->activeStudy() );
+ }
+
+ if ( aStudy )
+ {
+ aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
+ myEditObject->GetStudyEntry(),
+ GEOM::propertyName( GEOM::Dimensions ),
+ QVariant() );
+ }
+
+ redisplay( myEditObject.get() );
+ }
+
+ GEOMBase_Skeleton::DeactivateActiveDialog();
+}
+
//=================================================================================
// function : SetEditObject
// purpose :
@@ -967,26 +1036,26 @@ void MeasureGUI_ManageDimensionsDlg::PopulateList()
}
//=================================================================================
-// function : WarnUnsaved
+// function : HasUnsavedChanges
// purpose :
//=================================================================================
-bool MeasureGUI_ManageDimensionsDlg::WarnUnsaved()
+bool MeasureGUI_ManageDimensionsDlg::HasUnsavedChanges()
{
if ( myEditObject.isNull() )
{
- return true;
+ return false;
}
SalomeApp_Application* anApp = myGeomGUI->getApp();
if ( !anApp )
{
- return true;
+ return false;
}
SalomeApp_Study* aStudy = dynamic_cast( anApp->activeStudy() );
if ( !aStudy )
{
- return true;
+ return false;
}
GEOMGUI_DimensionProperty aCurrentState =
@@ -996,14 +1065,43 @@ bool MeasureGUI_ManageDimensionsDlg::WarnUnsaved()
QVariant() )
.value();
- if ( aCurrentState == mySavedPropertyState )
+ return aCurrentState != mySavedPropertyState;
+}
+
+//=================================================================================
+// function : AllowedToCancelChanges
+// purpose :
+//=================================================================================
+bool MeasureGUI_ManageDimensionsDlg::AllowedToCancelChanges()
+{
+ if ( !HasUnsavedChanges() )
{
return true;
}
int aResponse = SUIT_MessageBox::warning( this,
tr( "WRN_TITLE_UNSAVED" ),
- tr( "WRN_MSG_UNSAVED" ),
+ tr( "WRN_MSG_CHANGES_LOST" ),
+ QMessageBox::Ok,
+ QMessageBox::Cancel );
+
+ return aResponse == QMessageBox::Ok;
+}
+
+//=================================================================================
+// function : AllowedToSaveChanges
+// purpose :
+//=================================================================================
+bool MeasureGUI_ManageDimensionsDlg::AllowedToSaveChanges()
+{
+ if ( !HasUnsavedChanges() )
+ {
+ return false;
+ }
+
+ int aResponse = SUIT_MessageBox::warning( this,
+ tr( "WRN_TITLE_UNSAVED" ),
+ tr( "WRN_MSG_CHANGES_SAVE" ),
QMessageBox::Ok,
QMessageBox::Cancel );
diff --git a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.h b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.h
index 25d99b27f..91a28978f 100644
--- a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.h
+++ b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.h
@@ -79,12 +79,17 @@ protected slots:
virtual void ClickOnCancel();
bool ClickOnApply();
void OnFinish();
+ void OnActivateThisDialog();
+ void OnDeactivateThisDialog();
/* Utils */
private:
void SetEditObject( const GEOM::GeomObjPtr& );
void RestoreState();
void PopulateList();
+ bool HasUnsavedChanges();
+ bool AllowedToCancelChanges();
+ bool AllowedToSaveChanges();
bool WarnUnsaved();
int IdFromItem( QTreeWidgetItem* theItem );
int IdFromPrs( const Handle(AIS_InteractiveObject)& theAIS );
@@ -93,6 +98,9 @@ private:
void SelectInViewer( SOCC_Viewer* theViewer, const int theId );
void RedisplayObject();
+private:
+ void enterEvent(QEvent*);
+
private:
enum GroupItems
{