1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

1 Commits

Author SHA1 Message Date
ika
a716c3ec2a HOMAG patch for OCCT 6.7.0 2015-06-30 10:59:50 +03:00
144 changed files with 14932 additions and 2232 deletions

View File

@@ -241,7 +241,8 @@ is
KOI_Datum,
KOI_Shape,
KOI_Object,
KOI_Relation;
KOI_Relation,
KOI_Dimension;
--- Purpose: Declares the type of Interactive Object.
-- This is one of the following:
-- - the Datum

View File

@@ -48,6 +48,7 @@
#include <Select3D_SensitiveGroup.hxx>
#include <Select3D_SensitiveSegment.hxx>
#include <SelectMgr_Selection.hxx>
#include <Standard_ProgramError.hxx>
#include <UnitsAPI.hxx>
IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension)
@@ -300,7 +301,7 @@ void AIS_AngleDimension::Init()
//=======================================================================
gp_Pnt AIS_AngleDimension::GetCenterOnArc (const gp_Pnt& theFirstAttach,
const gp_Pnt& theSecondAttach,
const gp_Pnt& theCenter)
const gp_Pnt& theCenter) const
{
// construct plane where the circle and the arc are located
gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
@@ -623,30 +624,15 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
// Handle user-defined and automatic arrow placement
bool isArrowsExternal = false;
switch (aDimensionAspect->ArrowOrientation())
{
case Prs3d_DAO_External: isArrowsExternal = true; break;
case Prs3d_DAO_Internal: isArrowsExternal = false; break;
case Prs3d_DAO_Fit:
{
gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
Standard_Real aDimensionWidth = anAttachVector.Magnitude();
// add margin to ensure a small tail between text and arrow
Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
: 0.0;
Standard_Real anArrowsWidth = (anArrowLength + anArrowMargin) * 2.0;
isArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
break;
}
}
Standard_Boolean isArrowsExternal = Standard_False;
Standard_Integer aLabelPosition = LabelPosition_None;
FitTextAlignment (aLabelPosition, isArrowsExternal);
//Arrows positions and directions
gp_Vec aWPDir = gp_Vec (GetPlane().Axis().Direction());
// Get normal to plane for extension directions computing.
// Stored in the working plane normal is not suitable if flyout is negative.
gp_Vec aWPDir = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
gp_Dir aFirstExtensionDir = aWPDir ^ gp_Vec (myCenterPoint, aFirstAttach);
gp_Dir aSecondExtensionDir = aWPDir.Reversed() ^ gp_Vec (myCenterPoint, aSecondAttach);
@@ -670,33 +656,6 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
aFirstArrowEnd = aFirstAttach.Translated (-aFirstArrowVec);
aSecondArrowEnd = aSecondAttach.Translated (-aSecondArrowVec);
Standard_Integer aLabelPosition = LabelPosition_None;
// Handle user-defined and automatic text placement
switch (aDimensionAspect->TextHorizontalPosition())
{
case Prs3d_DTHP_Left : aLabelPosition |= LabelPosition_Left; break;
case Prs3d_DTHP_Right : aLabelPosition |= LabelPosition_Right; break;
case Prs3d_DTHP_Center: aLabelPosition |= LabelPosition_HCenter; break;
case Prs3d_DTHP_Fit:
{
gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
Standard_Real aDimensionWidth = anAttachVector.Magnitude();
Standard_Real anArrowsWidth = anArrowLength * 2.0;
Standard_Real aContentWidth = isArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
aLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
break;
}
}
switch (aDimensionAspect->TextVerticalPosition())
{
case Prs3d_DTVP_Above : aLabelPosition |= LabelPosition_Above; break;
case Prs3d_DTVP_Below : aLabelPosition |= LabelPosition_Below; break;
case Prs3d_DTVP_Center : aLabelPosition |= LabelPosition_VCenter; break;
}
// Group1: stenciling text and the angle dimension arc
Prs3d_Root::NewGroup (thePresentation);
@@ -729,7 +688,8 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
{
gp_Vec aDimensionDir (aFirstAttach, aSecondAttach);
gp_Pnt aTextPos = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
gp_Pnt aTextPos = myIsTextPositionFixed ? myFixedTextPosition
: GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
gp_Dir aTextDir = aDimensionDir;
DrawText (thePresentation,
@@ -807,7 +767,7 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
if (aHPosition != LabelPosition_Left)
{
DrawExtension (thePresentation,
anExtensionSize,
aDimensionAspect->ShortExtensionSize(),
aFirstArrowEnd,
aFirstExtensionDir,
THE_EMPTY_LABEL_STRING,
@@ -819,7 +779,7 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
if (aHPosition != LabelPosition_Right)
{
DrawExtension (thePresentation,
anExtensionSize,
aDimensionAspect->ShortExtensionSize(),
aSecondArrowEnd,
aSecondExtensionDir,
THE_EMPTY_LABEL_STRING,
@@ -891,6 +851,11 @@ Standard_Boolean AIS_AngleDimension::InitTwoEdgesAngle (gp_Pln& theComputedPlane
Standard_Boolean isParallelLines = Abs (aFirstLin.Angle (aSecondLin) - M_PI) <= Precision::Angular();
gp_Pnt aPoint = aFirstLine->Value (0.0);
if (isParallelLines && aFirstLin.Distance(aPoint) < Precision::Confusion())
{
// If two lines are parallel and distance between them is 0, we can't find a plane.
return Standard_False;
}
gp_Dir aNormal = isParallelLines
? gp_Vec (aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction())
: gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction());
@@ -1184,3 +1149,272 @@ Standard_Boolean AIS_AngleDimension::IsValidPoints (const gp_Pnt& theFirstPoint,
&& gp_Vec (theCenterPoint, theFirstPoint).Angle (
gp_Vec (theCenterPoint, theSecondPoint)) > Precision::Angular();
}
//=======================================================================
//function : GetTextPosition
//purpose :
//=======================================================================
const gp_Pnt AIS_AngleDimension::GetTextPosition() const
{
if (!IsValid())
{
return gp::Origin();
}
if (myIsTextPositionFixed)
{
return myFixedTextPosition;
}
// Counts text position according to the dimension parameters
gp_Pnt aTextPosition (gp::Origin());
Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
// Prepare label string and compute its geometrical width
Standard_Real aLabelWidth;
TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
// Handle user-defined and automatic arrow placement
Standard_Boolean isArrowsExternal = Standard_False;
Standard_Integer aLabelPosition = LabelPosition_None;
FitTextAlignment (aLabelPosition, isArrowsExternal);
// Get text position
switch (aLabelPosition & LabelPosition_HMask)
{
case LabelPosition_HCenter:
{
aTextPosition = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
}
break;
case LabelPosition_Left:
{
gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aFirstAttach);
Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
Standard_Real anOffset = isArrowsExternal
? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
: anExtensionSize;
gp_Vec anExtensionVec = gp_Vec(anExtensionDir)*(-anOffset);
aTextPosition = aFirstAttach.Translated (anExtensionVec);
}
break;
case LabelPosition_Right:
{
gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aSecondAttach);
Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
Standard_Real anOffset = isArrowsExternal
? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
: anExtensionSize;
gp_Vec anExtensionVec = gp_Vec(anExtensionDir)*(anOffset);
aTextPosition = aSecondAttach.Translated (anExtensionVec);
}
break;
}
return aTextPosition;
}
//=======================================================================
//function : SetTextPosition
//purpose :
//=======================================================================
void AIS_AngleDimension::SetTextPosition (const gp_Pnt& theTextPos)
{
if (!IsValid())
{
return;
}
// The text position point for angle dimension should belong to the working plane.
if (!GetPlane().Contains (theTextPos, Precision::Confusion()))
{
Standard_ProgramError::Raise ("The text position point for angle dimension doesn't belong to the working plane.");
}
myIsTextPositionFixed = Standard_True;
myFixedTextPosition = theTextPos;
Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
// Compute flyout direction vector.
gp_Dir aPlaneNormal = GetPlane().Axis().Direction();
gp_Dir aTargetPointsDir = gce_MakeDir (myFirstPoint, mySecondPoint);
// Build circle with radius that is equal to distance from text position to the center point.
Standard_Real aRadius = gp_Vec (myCenterPoint, theTextPos).Magnitude();
// Set attach points in positive direction of the flyout.
gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * aRadius);
gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * aRadius);
gce_MakeCirc aConstructCircle (myCenterPoint, GetPlane(), aRadius);
if (!aConstructCircle.IsDone())
{
return;
}
gp_Circ aCircle = aConstructCircle.Value();
// Default values
aDimensionAspect->SetExtensionSize (aDimensionAspect->ArrowAspect()->Length());
aDimensionAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);
Standard_Real aParamBeg = ElCLib::Parameter (aCircle, aFirstAttach);
Standard_Real aParamEnd = ElCLib::Parameter (aCircle, aSecondAttach);
ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
Standard_Real aTextPar = ElCLib::Parameter (aCircle , theTextPos);
// Horizontal center
if (aTextPar > aParamBeg && aTextPar < aParamEnd)
{
myFlyout = aRadius;
if (LayoutMode() == AIS_DLM_Automatic)
{
// Adjust text position so that text was aligned.
myFixedTextPosition = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
}
SetToUpdate();
return;
}
aParamBeg += M_PI;
aParamEnd += M_PI;
ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
if (aTextPar > aParamBeg && aTextPar < aParamEnd)
{
myFlyout = -aRadius;
if (LayoutMode() == AIS_DLM_Automatic)
{
// Adjust text position so that text was aligned.
aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
myFixedTextPosition = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
}
SetToUpdate();
return;
}
// Text on the extensions
gp_Lin aFirstLine = gce_MakeLin (myCenterPoint, myFirstPoint);
gp_Lin aSecondLine = gce_MakeLin (myCenterPoint, mySecondPoint);
gp_Pnt aFirstTextProj = AIS::Nearest (aFirstLine, theTextPos);
gp_Pnt aSecondTextProj = AIS::Nearest (aSecondLine, theTextPos);
Standard_Real aFirstDist = aFirstTextProj.Distance (theTextPos);
Standard_Real aSecondDist = aSecondTextProj.Distance (theTextPos);
if (aFirstDist <= aSecondDist)
{
aRadius = myCenterPoint.Distance (aFirstTextProj);
aDimensionAspect->SetExtensionSize (aFirstDist);
aDimensionAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left);
gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, myFirstPoint).Normalized().Scaled (aRadius);
if (aFirstTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion())
{
myFlyout = -aRadius;
}
else
{
myFlyout = aRadius;
}
}
else
{
aRadius = myCenterPoint.Distance (aSecondTextProj);
aDimensionAspect->SetExtensionSize (aSecondDist);
aDimensionAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right);
gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, mySecondPoint).Normalized().Scaled (aRadius);
if (aSecondTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion())
{
myFlyout = -aRadius;
}
else
{
myFlyout = aRadius;
}
}
}
//=======================================================================
//function : FitTextAlignment
//purpose :
//=======================================================================
void AIS_AngleDimension::FitTextAlignment (Standard_Integer& theLabelPosition,
Standard_Boolean& theIsArrowsExternal) const
{
Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
// Prepare label string and compute its geometrical width
Standard_Real aLabelWidth;
TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
// add margins to label width
if (aDimensionAspect->IsText3d())
{
aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
}
gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
// Handle user-defined and automatic arrow placement
switch (aDimensionAspect->ArrowOrientation())
{
case Prs3d_DAO_External: theIsArrowsExternal = true; break;
case Prs3d_DAO_Internal: theIsArrowsExternal = false; break;
case Prs3d_DAO_Fit:
{
gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
Standard_Real aDimensionWidth = anAttachVector.Magnitude();
// Add margin to ensure a small tail between text and arrow
Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
: 0.0;
Standard_Real anArrowsWidth = (anArrowLength + anArrowMargin) * 2.0;
theIsArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
break;
}
}
// Handle user-defined and automatic text placement
switch (aDimensionAspect->TextHorizontalPosition())
{
case Prs3d_DTHP_Left : theLabelPosition |= LabelPosition_Left; break;
case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break;
case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break;
case Prs3d_DTHP_Fit:
{
gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
Standard_Real aDimensionWidth = anAttachVector.Magnitude();
Standard_Real anArrowsWidth = anArrowLength * 2.0;
Standard_Real aContentWidth = theIsArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
theLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
break;
}
}
switch (aDimensionAspect->TextVerticalPosition())
{
case Prs3d_DTVP_Above : theLabelPosition |= LabelPosition_Above; break;
case Prs3d_DTVP_Below : theLabelPosition |= LabelPosition_Below; break;
case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break;
}
}

View File

@@ -197,6 +197,16 @@ public:
Standard_EXPORT virtual void SetModelUnits (const TCollection_AsciiString& theUnits);
//! Principle of horizontal text alignment settings:
//! - divide circle into two halfs according to attachment points
//! - if aTextPos is between attach points -> Center + positive flyout
//! - if aTextPos is not between attach points but in this half -> Left or Right + positive flyout
//! - if aTextPos is between reflections of attach points -> Center + negative flyout
//! - if aTextPos is not between reflections of attach points -> Left or Right + negative flyout
Standard_EXPORT virtual void SetTextPosition (const gp_Pnt& theTextPos);
Standard_EXPORT virtual const gp_Pnt GetTextPosition () const;
public:
DEFINE_STANDARD_RTTI (AIS_AngleDimension)
@@ -212,7 +222,7 @@ protected:
//! @return the center of the dimension arc (the main dimension line in case of angle).
Standard_EXPORT gp_Pnt GetCenterOnArc (const gp_Pnt& theFirstAttach,
const gp_Pnt& theSecondAttach,
const gp_Pnt& theCenter);
const gp_Pnt& theCenter) const;
//! Draws main dimension line (arc).
//! @param thePresentation [in] the dimension presentation.
@@ -247,6 +257,15 @@ protected:
const Standard_Integer theMode,
const Standard_Integer theLabelPosition);
//! Fits text alignment relatively to the dimension line.
//! @param theLabelPosition [out] the label position, contains bits that defines
//! vertical and horizontal alignment. (for internal usage in count text position)
//! @param theIsArrowExternal [out] is the arrows external,
//! if arrow orientation in the dimension aspect is Prs3d_DAO_Fit, it fits arrow
//! orientation automatically.
Standard_EXPORT void FitTextAlignment (Standard_Integer& theLabelPosition,
Standard_Boolean& theIsArrowsExternal) const;
protected:
Standard_EXPORT virtual void ComputePlane();

View File

@@ -296,7 +296,7 @@ void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)&
gp_Pnt aFirstPnt (gp::Origin());
gp_Pnt aSecondPnt (gp::Origin());
ComputeSidePoints (myCircle, GetPlane(), aFirstPnt, aSecondPnt);
ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt);
}
@@ -315,7 +315,7 @@ void AIS_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selec
gp_Pnt aFirstPnt (gp::Origin());
gp_Pnt aSecondPnt (gp::Origin());
ComputeSidePoints (myCircle, GetPlane(), aFirstPnt, aSecondPnt);
ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
ComputeLinearFlyouts (theSelection, theEntityOwner, aFirstPnt, aSecondPnt);
}
@@ -324,15 +324,14 @@ void AIS_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selec
//function : ComputeSidePoints
//purpose :
//=======================================================================
void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& /*theCircle*/,
const gp_Pln& /*thePlane*/,
void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle,
gp_Pnt& theFirstPnt,
gp_Pnt& theSecondPnt)
{
theFirstPnt = AnchorPoint();
gp_Vec aRadiusVector (myCircle.Location(), theFirstPnt);
theSecondPnt = myCircle.Location().Translated (-aRadiusVector);
gp_Vec aRadiusVector (theCircle.Location(), theFirstPnt);
theSecondPnt = theCircle.Location().Translated (-aRadiusVector);
}
//=======================================================================
@@ -358,3 +357,33 @@ Standard_Boolean AIS_DiameterDimension::IsValidAnchor (const gp_Circ& theCircle,
return Abs (anAnchorDist - aRadius) > Precision::Confusion()
&& aCirclePlane.Contains (theAnchor, Precision::Confusion());
}
//=======================================================================
//function : GetTextPosition
//purpose :
//=======================================================================
const gp_Pnt AIS_DiameterDimension::GetTextPosition () const
{
if (myIsTextPositionFixed)
{
return myFixedTextPosition;
}
// Counts text position according to the dimension parameters
return GetTextPositionForLinear (myAnchorPoint, myCircle.Location());
}
//=======================================================================
//function : GetTextPosition
//purpose :
//=======================================================================
void AIS_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos)
{
if (!myIsValid)
{
return;
}
SetTextPositionForLinear (myAnchorPoint, myCircle.Location(), theTextPos);
SetToUpdate();
}

View File

@@ -114,15 +114,19 @@ public:
Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Shape& theShape);
//! @return the display units string.
Standard_EXPORT virtual const TCollection_AsciiString& GetDisplayUnits () const;
Standard_EXPORT virtual const TCollection_AsciiString& GetDisplayUnits() const;
//! @return the model units string.
Standard_EXPORT virtual const TCollection_AsciiString& GetModelUnits () const;
Standard_EXPORT virtual const TCollection_AsciiString& GetModelUnits() const;
Standard_EXPORT virtual void SetDisplayUnits (const TCollection_AsciiString& theUnits);
Standard_EXPORT virtual void SetModelUnits (const TCollection_AsciiString& theUnits);
Standard_EXPORT virtual void SetTextPosition (const gp_Pnt& theTextPos);
Standard_EXPORT virtual const gp_Pnt GetTextPosition() const;
public:
DEFINE_STANDARD_RTTI(AIS_DiameterDimension)
@@ -154,16 +158,14 @@ protected:
protected:
//! Compute points on the circle sides for the specified dimension plane.
//! Compute points on the circle sides for the dimension plane.
//! Program error exception is raised if the dimension plane "x" direction
//! is orthogonal to plane (the "impossible" case). The passed dimension plane
//! is the one specially computed to locate dimension presentation in circle.
//! @param theCircle [in] the circle.
//! @param thePlane [in] the dimension presentation plane computed.
//! @param theFirstPnt [out] the first point.
//! @param theSecondPnt [out] the second point.
Standard_EXPORT void ComputeSidePoints (const gp_Circ& theCircle,
const gp_Pln& thePlane,
gp_Pnt& theFirstPnt,
gp_Pnt& theSecondPnt);

View File

@@ -25,11 +25,13 @@
#include <ElCLib.hxx>
#include <Font_BRepFont.hxx>
#include <GC_MakeCircle.hxx>
#include <Geom_Line.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom_Circle.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <gce_MakeDir.hxx>
#include <gce_MakeLin.hxx>
#include <gce_MakePln.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_AspectLine3d.hxx>
@@ -57,6 +59,7 @@
#include <Select3D_SensitiveFace.hxx>
#include <Select3D_SensitiveTriangle.hxx>
#include <Standard_CString.hxx>
#include <Standard_ProgramError.hxx>
#include <StdPrs_ShadedShape.hxx>
#include <StdPrs_WFShape.hxx>
#include <TCollection_AsciiString.hxx>
@@ -68,7 +71,6 @@
#include <Units_UnitsDictionary.hxx>
#include <UnitsAPI.hxx>
#include <UnitsAPI_SystemUnits.hxx>
#include <Standard_ProgramError.hxx>
IMPLEMENT_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT(AIS_Dimension, AIS_InteractiveObject)
@@ -97,6 +99,7 @@ AIS_Dimension::AIS_Dimension (const AIS_KindOfDimension theType)
: AIS_InteractiveObject(),
myCustomValue (0.0),
myIsValueCustom (Standard_False),
myLayoutMode (AIS_DLM_Automatic),
mySpecialSymbol (' '),
myDisplaySpecialSymbol (AIS_DSS_No),
myGeometryType (GeometryType_UndefShapes),
@@ -235,6 +238,15 @@ void AIS_Dimension::SetFlyout (const Standard_Real theFlyout)
SetToUpdate();
}
//=======================================================================
//function : SetLayoutMode
//purpose :
//=======================================================================
void AIS_Dimension::SetLayoutMode (const AIS_DimensionLayoutMode theLayoutMode)
{
myLayoutMode = theLayoutMode;
}
//=======================================================================
//function : GetDisplayUnits
//purpose :
@@ -651,27 +663,11 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
}
// handle user-defined and automatic arrow placement
bool isArrowsExternal = false;
switch (aDimensionAspect->ArrowOrientation())
{
case Prs3d_DAO_External: isArrowsExternal = true; break;
case Prs3d_DAO_Internal: isArrowsExternal = false; break;
case Prs3d_DAO_Fit:
{
// add margin to ensure a small tail between text and arrow
Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
: 0.0;
Standard_Boolean isArrowsExternal = Standard_False;
Standard_Integer aLabelPosition = LabelPosition_None;
Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint);
Standard_Real anArrowsWidth = theIsOneSide
? anArrowLength + anArrowMargin
: (anArrowLength + anArrowMargin) * 2.0;
isArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
break;
}
}
FitTextAlignmentForLinear (theFirstPoint, theSecondPoint, theIsOneSide,
aLabelPosition, isArrowsExternal);
// compute arrows positions and directions
gp_Dir aFirstArrowDir = aDimensionLine.Direction().Reversed();
@@ -701,32 +697,6 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
gp_Pnt aCenterLineEnd = isArrowsExternal || theIsOneSide
? aLineEndPoint : aSecondArrowEnd;
Standard_Integer aLabelPosition = LabelPosition_None;
// handle user-defined and automatic text placement
switch (aDimensionAspect->TextHorizontalPosition())
{
case Prs3d_DTHP_Left : aLabelPosition |= LabelPosition_Left; break;
case Prs3d_DTHP_Right : aLabelPosition |= LabelPosition_Right; break;
case Prs3d_DTHP_Center: aLabelPosition |= LabelPosition_HCenter; break;
case Prs3d_DTHP_Fit:
{
Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint);
Standard_Real anArrowsWidth = theIsOneSide ? anArrowLength : 2.0 * anArrowLength;
Standard_Real aContentWidth = isArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
aLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
break;
}
}
// handle vertical text placement options
switch (aDimensionAspect->TextVerticalPosition())
{
case Prs3d_DTVP_Above : aLabelPosition |= LabelPosition_Above; break;
case Prs3d_DTVP_Below : aLabelPosition |= LabelPosition_Below; break;
case Prs3d_DTVP_Center : aLabelPosition |= LabelPosition_VCenter; break;
}
switch (aLabelPosition & LabelPosition_HMask)
{
@@ -738,7 +708,8 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
// add label on dimension or extension line to presentation
Prs3d_Root::NewGroup (thePresentation);
gp_Pnt aTextPos = (aCenterLineBegin.XYZ() + aCenterLineEnd.XYZ()) * 0.5;
gp_Pnt aTextPos = myIsTextPositionFixed ? myFixedTextPosition
: (aCenterLineBegin.XYZ() + aCenterLineEnd.XYZ()) * 0.5;
gp_Dir aTextDir = aDimensionLine.Direction();
// add text primitives
@@ -829,12 +800,12 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
// add arrow extension lines to presentation
Prs3d_Root::NewGroup (thePresentation);
DrawExtension (thePresentation, anExtensionSize,
DrawExtension (thePresentation, aDimensionAspect->ShortExtensionSize(),
aFirstArrowEnd, aFirstExtensionDir,
THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
if (!theIsOneSide)
{
DrawExtension (thePresentation, anExtensionSize,
DrawExtension (thePresentation, aDimensionAspect->ShortExtensionSize(),
aSecondArrowEnd, aSecondExtensionDir,
THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
}
@@ -898,7 +869,7 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
// add extension lines for external arrows
Prs3d_Root::NewGroup (thePresentation);
DrawExtension (thePresentation, anExtensionSize,
DrawExtension (thePresentation, aDimensionAspect->ShortExtensionSize(),
aSecondArrowEnd, aSecondExtensionDir,
THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
}
@@ -958,7 +929,7 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
// add extension lines for external arrows
Prs3d_Root::NewGroup (thePresentation);
DrawExtension (thePresentation, anExtensionSize,
DrawExtension (thePresentation, aDimensionAspect->ShortExtensionSize(),
aFirstArrowEnd, aFirstExtensionDir,
THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
}
@@ -1142,7 +1113,6 @@ Standard_Boolean AIS_Dimension::InitCircularDimension (const TopoDS_Shape& theSh
theCircle = aMkCirc.Value()->Circ();
}
gp_Vec aVec = gp_Vec (theCircle.Location(), aCurPos).Normalized();
aFirstPoint = ElCLib::Value (aFirstU, theCircle);
aLastPoint = ElCLib::Value (aLastU, theCircle);
}
@@ -1357,3 +1327,283 @@ void AIS_Dimension::PointsForArrow (const gp_Pnt& thePeakPnt,
theSidePnt1 = ElCLib::Value ( anEdgeLength, anEdgeLin);
theSidePnt2 = ElCLib::Value (-anEdgeLength, anEdgeLin);
}
//=======================================================================
//function : GetTextPositionForLinear
//purpose :
//=======================================================================
Standard_Boolean AIS_Dimension::SetTextPositionForLinear (const gp_Pnt& theFirstPoint,
const gp_Pnt& theSecondPoint,
const gp_Pnt& theTextPos)
{
if (!IsValid())
{
return Standard_False;
}
myIsTextPositionFixed = Standard_True;
myFixedTextPosition = theTextPos;
#if 1 //HOMAG
//Don't set new plane if the text position lies on the attachment points line.
gp_Dir aTargetPointsDir = gce_MakeDir (theFirstPoint, theSecondPoint);
gp_Lin aTargetPointsLin (theFirstPoint, aTargetPointsDir);
if (!aTargetPointsLin.Contains (theTextPos, Precision::Confusion()))
{
myPlane = gce_MakePln (theTextPos, theFirstPoint, theSecondPoint);
myIsPlaneCustom = Standard_False;
}
// Compute dimension line points.
gp_Dir aPlaneNormal = GetPlane().Axis().Direction();
gp_Vec aTargetPointsVec (theFirstPoint, theSecondPoint);
//check if the target and plane dir not parallel. Else the cross
//product fails.
if (aPlaneNormal.IsParallel(aTargetPointsDir, Precision::Angular()))
return Standard_False;
#else
//Set new automatic plane.
myPlane = gce_MakePln (theTextPos, theFirstPoint, theSecondPoint);
myIsPlaneCustom = Standard_False;
// Compute dimension line points.
gp_Dir aPlaneNormal = GetPlane().Axis().Direction();
gp_Dir aTargetPointsDir = gce_MakeDir (theFirstPoint, theSecondPoint);
gp_Vec aTargetPointsVec (theFirstPoint, theSecondPoint);
#endif
// Compute flyout direction vector.
gp_Dir aPositiveFlyout = aPlaneNormal ^ aTargetPointsDir;
// Set flyout.
gp_Vec aFirstToTextVec (theFirstPoint, theTextPos);
Standard_Real aCos = aFirstToTextVec.Normalized() * gp_Vec (aTargetPointsDir);
gp_Pnt aTextPosProj = theFirstPoint.Translated
(gp_Vec (aTargetPointsDir)*aFirstToTextVec.Magnitude()*aCos);
// Compute flyout value and direction.
gp_Vec aFlyoutVector = gp_Vec (aTextPosProj, theTextPos);
#if 1 //HOMAG
//Check if the vectors magnitude is not 0! Else
//it does generate an exception for IsOpposite.
myFlyout = 0.0;
if (aFlyoutVector.Magnitude() > Precision::Confusion())
{
myFlyout = (gp_Dir (aFlyoutVector).IsOpposite (aPositiveFlyout, Precision::Angular()))
? -aFlyoutVector.Magnitude()
: (aFlyoutVector.Magnitude());
}
#else
myFlyout = (gp_Dir (aFlyoutVector).IsOpposite (aPositiveFlyout, Precision::Angular()))
? -aFlyoutVector.Magnitude()
: (aFlyoutVector.Magnitude());
#endif
// Set horisontal text alignment.
if (aCos < 0.0)
{
myDrawer->DimensionAspect()->SetTextHorizontalPosition (Prs3d_DTHP_Left);
myDrawer->DimensionAspect()->SetExtensionSize (theTextPos.Distance (theFirstPoint.Translated (aFlyoutVector)));
}
else if (aTextPosProj.Distance (theFirstPoint) > theFirstPoint.Distance (theSecondPoint))
{
myDrawer->DimensionAspect()->SetTextHorizontalPosition (Prs3d_DTHP_Right);
myDrawer->DimensionAspect()->SetExtensionSize (theTextPos.Distance (theSecondPoint.Translated (aFlyoutVector)));
}
else
{
myDrawer->DimensionAspect()->SetTextHorizontalPosition (Prs3d_DTHP_Center);
if (LayoutMode() == AIS_DLM_Automatic)
{
// Adjust text position so that text was aligned.
myFixedTextPosition = theFirstPoint.Translated (aTargetPointsVec * 0.5 + aFlyoutVector);
}
}
return Standard_True;
}
//=======================================================================
//function : GetTextPositionForLinear
//purpose :
//=======================================================================
gp_Pnt AIS_Dimension::GetTextPositionForLinear (const gp_Pnt& theFirstPoint,
const gp_Pnt& theSecondPoint,
const Standard_Boolean theIsOneSide) const
{
if (!myIsValid)
{
return gp::Origin();
}
gp_Pnt aTextPosition (gp::Origin());
Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
// Get label alignment and arrow orientation.
Standard_Integer aLabelPosition = 0;
Standard_Boolean isArrowsExternal = Standard_False;
FitTextAlignmentForLinear (theFirstPoint, theSecondPoint, theIsOneSide,
aLabelPosition, isArrowsExternal);
// Compute dimension line points.
gp_Dir aPlaneNormal = GetPlane().Axis().Direction();
gp_Vec aTargetPointsVec (theFirstPoint, theSecondPoint);
// Compute flyout direction vector
gp_Dir aFlyoutVector = aPlaneNormal ^ gp_Dir(aTargetPointsVec);
// create lines for layouts
gp_Lin aLine1 (theFirstPoint, aFlyoutVector);
gp_Lin aLine2 (theSecondPoint, aFlyoutVector);
// Get flyout end points
gp_Pnt aLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout(), aLine1);
gp_Pnt aLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2);
// Get text position.
switch (aLabelPosition & LabelPosition_HMask)
{
case LabelPosition_Left:
{
gp_Dir aTargetPointsDir = gce_MakeDir (theFirstPoint, theSecondPoint);
Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
Standard_Real anOffset = isArrowsExternal
? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
: anExtensionSize;
gp_Vec anExtensionVec = gp_Vec(aTargetPointsDir)*(-anOffset);
aTextPosition = aLineEndPoint.Translated (anExtensionVec);
}
break;
case LabelPosition_Right:
{
gp_Dir aTargetPointsDir = gce_MakeDir (theFirstPoint, theSecondPoint);
Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
Standard_Real anOffset = isArrowsExternal
? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
: anExtensionSize;
gp_Vec anExtensionVec = gp_Vec(aTargetPointsDir)*(anOffset);
aTextPosition = aLineBegPoint.Translated (anExtensionVec);
}
break;
case LabelPosition_HCenter:
{
aTextPosition = (aLineBegPoint.XYZ() + aLineEndPoint.XYZ()) * 0.5;
}
break;
}
return aTextPosition;
}
//=======================================================================
//function : FitTextAlignment
//purpose :
//=======================================================================
void AIS_Dimension::FitTextAlignmentForLinear (const gp_Pnt& theFirstPoint,
const gp_Pnt& theSecondPoint,
const Standard_Boolean theIsOneSide,
Standard_Integer& theLabelPosition,
Standard_Boolean& theIsArrowsExternal) const
{
theLabelPosition = LabelPosition_None;
theIsArrowsExternal = Standard_False;
// Compute dimension line points
gp_Ax1 aPlaneNormal = GetPlane().Axis();
gp_Dir aTargetPointsVector = gce_MakeDir (theFirstPoint, theSecondPoint);
// compute flyout direction vector
gp_Dir aFlyoutVector = aPlaneNormal.Direction() ^ aTargetPointsVector;
// create lines for layouts
gp_Lin aLine1 (theFirstPoint, aFlyoutVector);
gp_Lin aLine2 (theSecondPoint, aFlyoutVector);
// Get flyout end points
gp_Pnt aLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout(), aLine1);
gp_Pnt aLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2);
Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
gp_Lin aDimensionLine = gce_MakeLin (aLineBegPoint, aLineEndPoint);
// For extensions we need to know arrow size, text size and extension size: get it from aspect
Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
// prepare label string and compute its geometrical width
Standard_Real aLabelWidth;
TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
// Add margins to cut dimension lines for 3d text
if (aDimensionAspect->IsText3d())
{
aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
}
// Handle user-defined and automatic arrow placement
switch (aDimensionAspect->ArrowOrientation())
{
case Prs3d_DAO_External: theIsArrowsExternal = true; break;
case Prs3d_DAO_Internal: theIsArrowsExternal = false; break;
case Prs3d_DAO_Fit:
{
// Add margin to ensure a small tail between text and arrow
Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
: 0.0;
Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint);
Standard_Real anArrowsWidth = theIsOneSide
? anArrowLength + anArrowMargin
: (anArrowLength + anArrowMargin) * 2.0;
theIsArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
break;
}
}
// Compute arrows positions and directions
gp_Dir aFirstArrowDir = aDimensionLine.Direction().Reversed();
gp_Dir aSecondArrowDir = aDimensionLine.Direction();
gp_Dir aFirstExtensionDir = aDimensionLine.Direction().Reversed();
gp_Dir aSecondExtensionDir = aDimensionLine.Direction();
if (theIsArrowsExternal)
{
aFirstArrowDir.Reverse();
aSecondArrowDir.Reverse();
}
// Handle user-defined and automatic text placement
switch (aDimensionAspect->TextHorizontalPosition())
{
case Prs3d_DTHP_Left : theLabelPosition |= LabelPosition_Left; break;
case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break;
case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break;
case Prs3d_DTHP_Fit:
{
Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint);
Standard_Real anArrowsWidth = theIsOneSide ? anArrowLength : 2.0 * anArrowLength;
Standard_Real aContentWidth = theIsArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
theLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
break;
}
}
// Handle vertical text placement options
switch (aDimensionAspect->TextVerticalPosition())
{
case Prs3d_DTVP_Above : theLabelPosition |= LabelPosition_Above; break;
case Prs3d_DTVP_Below : theLabelPosition |= LabelPosition_Below; break;
case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break;
}
}

View File

@@ -16,6 +16,7 @@
#ifndef _AIS_Dimension_HeaderFile
#define _AIS_Dimension_HeaderFile
#include <AIS_DimensionLayoutMode.hxx>
#include <AIS_DimensionSelectionMode.hxx>
#include <AIS_DimensionOwner.hxx>
#include <AIS_DisplaySpecialSymbol.hxx>
@@ -56,11 +57,11 @@ DEFINE_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject)
//! The specified by user units are stored in the dimension's drawer.
//!
//! As a drawing, the dimension is composed from the following components:
//! - Attachement (binding) points. The points where the dimension lines attaches to, for
//! - Attachment (binding) points. The points where the dimension lines attaches to, for
//! length dimensions the distances are measured between these points.
//! - Main dimension line. The which extends from the attachement points in "up" direction,
//! - Main dimension line. The which extends from the attachment points in "up" direction,
//! and which contains text label on it with value string.
//! - Flyouts. The lines connecting the attachement points with main dimension line.
//! - Flyouts. The lines connecting the attachment points with main dimension line.
//! - Extension. The lines used to extend the main dimension line in the cases when text
//! or arrows do not fit into the main dimension line due to their size.
//! - Arrows.
@@ -75,7 +76,7 @@ DEFINE_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject)
//! |flyout flyout|
//! | |
//! +-----------------------------------+
//! attachement attachement
//! attachment attachment
//! point point
//!
//! Angular dimensions:
@@ -130,19 +131,46 @@ DEFINE_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject)
//!
//! The dimension support two local selection modes: main dimension line selection and text label
//! selection. These modes can be used to develop interactive modification of dimension presentations.
//! The component hilighting in these selection modes is provided by AIS_DimensionOwner class.
//! The component highlighting in these selection modes is provided by AIS_DimensionOwner class.
//! Please note that selection is unavailable until the presentation is computed.
//!
//! The specific drawing attributes are controlled through Prs3d_DimensionAspect. The one can change
//! color, arrows, text and arrow style and specify positioning of value label by setting corresponding
//! values to the aspect.
//!
//! Such set of parameters that consists of:
//! - flyout size and direction,
//! - user-defined dimension plane,
//! - horizontal and vertical text alignment
//! can be uniquely replaced with text position in 3d space. Therefore, there are methods to convert
//! this set of parameters to the text position and vice versa:
//!
//! - If the fixed text position is defined by user, called SetTextPosition (theTextPos) method converts
//! this 3d point to the set of parameters including adjusting of the dimension plane (this plane will be
//! automatic plane, NOT user-defined one).
//! If the fixed text position is set, the flag myIsFixedTextPosition is set to TRUE.
//! ATTENSION! myIsFixedTextPosition fixes all parameters of the set from recomputing inside
//! SetMeasureGeometry() methods. Parameters from the set can be changed only directly by user with
//! calls of setters. In this case changing of some parameter from the set leads to disabling the of
//! fixed text position (myIsFixedTextPosition is set to FALSE).
//! If the fixed text position is set and geometry is changed by user (SetMeasureGeometry() method
//! is called) and the geometry doesn't satisfy computed dimension plane, the dimension is not valid.
//!
//! - If the set of parameters was set by user (may be without the user-defined plane or with it),
//! it can be converted to the text position by calling the method GetTextPosition(). In this case
//! the text position is NOT fixed, and SetMeasureGeometry() without user-defined plane adjusts
//! the automatic plane according input geometry (if it is possible).
//!
//! ATTENSION! By default after SetTextPosition() call the text label is automatically aligned.
//! This means that if text was placed not on the extensions (between attachment points), it will
//! centered. If you want to uncentered text use SetLayoutMode (DLM_Manual), otherwise dimension
//! layout mode will be set as automatic and text will be aligned and centered.
class AIS_Dimension : public AIS_InteractiveObject
{
protected:
//! Geometry type defines type of shapes on which the dimension is to be built.
//! Some type of geometry allows automatical plane computing and
//! Some type of geometry allows automatic plane computing and
//! can be built without user-defined plane
//! Another types can't be built without user-defined plane.
enum GeometryType
@@ -212,8 +240,8 @@ public:
//! By default, if plane is not defined by user, it is computed automatically
//! after dimension geometry is computed.
//! If computed dimension geometry (points) can't be placed on the user-defined
//! plane, dimension geometry was set as unvalid (validity flag is set to false)
//! and dimension presentation wil not be computed.
//! plane, dimension geometry was set as invalid (validity flag is set to false)
//! and dimension presentation will not be computed.
//! If user-defined plane allow geometry placement on it, it will be used for
//! computing of the dimension presentation.
//! @return dimension plane used for presentation computing.
@@ -233,6 +261,22 @@ public:
//! computed automatically.
Standard_EXPORT void UnsetCustomPlane() { myIsPlaneCustom = Standard_False; }
//! @return TRUE if text position is set by user with method SetTextPosition().
Standard_Boolean IsTextPositionCustom () const
{
return myIsTextPositionFixed;
}
//! Fixes the absolute text position and adjusts flyout, plane and text alignment
//! according to it. Updates presentation if the text position is valid.
//! ATTENTION! It does not change vertical text alignment.
//! @param theTextPos [in] the point of text position.
virtual void SetTextPosition (const gp_Pnt& /*theTextPos*/) { }
//! Computes absolute text position from dimension parameters
//! (flyout, plane and text alignment).
virtual const gp_Pnt GetTextPosition () const { return gp_Pnt(); }
public:
//! Gets the dimension aspect from AIS object drawer.
@@ -256,7 +300,7 @@ public:
//! @return the kind of interactive.
virtual AIS_KindOfInteractive Type() const
{
return AIS_KOI_Relation;
return AIS_KOI_Dimension;
}
//! Returns true if the class of objects accepts the display mode theMode.
@@ -321,13 +365,24 @@ public:
Standard_EXPORT void SetFlyout (const Standard_Real theFlyout);
//! Check that the input geometry for dimension is valid and the
//! presentation can be succesfully computed.
//! presentation can be successfully computed.
//! @return TRUE if dimension geometry is ok.
Standard_Boolean IsValid() const
{
return myIsValid;
}
//! @return layout mode - how the label will be placed
//! relative to the dimension line.
AIS_DimensionLayoutMode LayoutMode() const
{
return myLayoutMode;
}
//! Sets layout mode.
//! @param theLayoutMode [in] the layout mode.
Standard_EXPORT void SetLayoutMode (const AIS_DimensionLayoutMode theLayoutMode);
public:
DEFINE_STANDARD_RTTI(AIS_Dimension)
@@ -426,6 +481,42 @@ protected:
gp_Circ& theCircle,
gp_Pnt& theMiddleArcPoint,
Standard_Boolean& theIsClosed);
//! Produce points for triangular arrow face.
//! @param thePeakPnt [in] the arrow peak position.
//! @param theDirection [in] the arrow direction.
//! @param thePlane [in] the face plane.
//! @param theArrowLength [in] the length of arrow.
//! @param theArrowAngle [in] the angle of arrow.
//! @param thePeakPnt [in] the arrow peak point.
//! @param theSidePnt1 [in] the first side point.
//! @param theSidePnt2 [in] the second side point.
Standard_EXPORT void PointsForArrow (const gp_Pnt& thePeakPnt,
const gp_Dir& theDirection,
const gp_Dir& thePlane,
const Standard_Real theArrowLength,
const Standard_Real theArrowAngle,
gp_Pnt& theSidePnt1,
gp_Pnt& theSidePnt2);
//! Compute point of text position for dimension parameters
//! for linear kinds of dimensions (length, radius, diameter).
Standard_EXPORT gp_Pnt GetTextPositionForLinear (const gp_Pnt& theFirstPoint,
const gp_Pnt& theSecondPoint,
const Standard_Boolean theIsOneSide = Standard_False) const;
//! Adjust dimension parameters for the given point of new text position
//! for linear kinds of dimensions (length, radius, diameter).
Standard_EXPORT Standard_Boolean SetTextPositionForLinear (const gp_Pnt& theFirstPoint,
const gp_Pnt& theSecondPoint,
const gp_Pnt& theTextPos);
//! Fits text alignment relatively to the dimension line.
void FitTextAlignmentForLinear (const gp_Pnt& theFirstPoint,
const gp_Pnt& theSecondPoint,
const Standard_Boolean theIsOneSide,
Standard_Integer& theLabelPosition,
Standard_Boolean& theIsArrowsExternal) const;
protected: //! @name Behavior to implement
@@ -455,22 +546,6 @@ protected: //! @name Behavior to implement
virtual void ComputeFlyoutSelection (const Handle(SelectMgr_Selection)&,
const Handle(SelectMgr_EntityOwner)&) {}
//! Produce points for triangular arrow face.
//! @param thePeakPnt [in] the arrow peak position.
//! @param theDirection [in] the arrow direction.
//! @param thePlane [in] the face plane.
//! @param theArrowLength [in] the length of arrow.
//! @param theArrowAngle [in] the angle of arrow.
//! @param thePeakPnt [in] the arrow peak point.
//! @param theSidePnt1 [in] the first side point.
//! @param theSidePnt2 [in] the second side point.
Standard_EXPORT void PointsForArrow (const gp_Pnt& thePeakPnt,
const gp_Dir& theDirection,
const gp_Dir& thePlane,
const Standard_Real theArrowLength,
const Standard_Real theArrowAngle,
gp_Pnt& theSidePnt1,
gp_Pnt& theSidePnt2);
//! Base procedure of computing selection (based on selection geometry data).
//! @param theSelection [in] the selection structure to will with primitives.
@@ -525,7 +600,7 @@ protected: //! @name Selection geometry
}
}
//! Add new curve entry and return the referenece to populate it.
//! Add new curve entry and return the reference to populate it.
Curve& NewCurve()
{
DimensionLine.Append( new Curve );
@@ -533,7 +608,7 @@ protected: //! @name Selection geometry
return *aLastCurve;
}
//! Add new arrow entry and return the referenece to populate it.
//! Add new arrow entry and return the reference to populate it.
Arrow& NewArrow()
{
Arrows.Append( new Arrow );
@@ -550,6 +625,12 @@ protected: //! @name Value properties
Standard_Real myCustomValue; //!< Value of the dimension (computed or user-defined).
Standard_Boolean myIsValueCustom; //!< Is user-defined value.
protected: //! @name Fixed text position properties
AIS_DimensionLayoutMode myLayoutMode; //!< controls how label will be placed relatively to the line.
gp_Pnt myFixedTextPosition; //!< Stores text position fixed by user.
Standard_Boolean myIsTextPositionFixed; //!< Is the text label position fixed by user.
protected: //! @name Units properties
Standard_ExtCharacter mySpecialSymbol; //!< Special symbol.

View File

@@ -0,0 +1,24 @@
// This file is generated by WOK (CPPExt).
// Please do not edit this file; modify original file instead.
// The copyright and license terms as defined for the original file apply to
// this header file considered to be the "object code" form of the original source.
#ifndef _AIS_DimensionLayoutMode_HeaderFile
#define _AIS_DimensionLayoutMode_HeaderFile
//! Specifies dimension layout mode: how text and dimension line <br>
//! will be placed. <br>
//! If DLM_Automatic mode is chosen text will be aligned automatically <br>
//! and centered if it is placed not on the extensions. <br>
//! If DLM_Manual mode is chosen text position will not been centered <br>
//! and is placed just where its position is set by user. <br>
enum AIS_DimensionLayoutMode {
AIS_DLM_Automatic,
AIS_DLM_Manual
};
#ifndef _Standard_PrimitiveTypes_HeaderFile
#include <Standard_PrimitiveTypes.hxx>
#endif
#endif

View File

@@ -138,7 +138,8 @@ uses
EntityOwner from SelectMgr,
TypeOfFacingModel from Aspect,
Array1OfPnt2d from TColgp,
Transformation from Geom
Transformation from Geom,
SequenceOfShape from TopTools
is
@@ -2104,6 +2105,7 @@ fields
-- InitDetected(), MoreDetected(), NextDetected(), DetectedCurrentShape(), DetectedCurrentObject().
myZDetectionFlag: Boolean from Standard;
-- This variables is used by SetZDetection() and ZDetection() methods
myAISDetectedShapes : SequenceOfShape from TopTools;
-- abd:
myIsAutoActivateSelMode : Boolean from Standard;

View File

@@ -238,15 +238,14 @@ void AIS_InteractiveContext::DisplayedObjects(AIS_ListOfInteractive& aListOfIO,
#endif
//parse all local contexts...
#ifdef DEBUG
Standard_Integer NbDisp;
for(AIS_DataMapIteratorOfDataMapOfILC it1(myLocalContexts);it1.More();it1.Next()){
const Handle(AIS_LocalContext)& LC = it1.Value();
NbDisp = LC->DisplayedObjects(theMap);
#ifdef DEBUG
cout<<"\tIn Local Context "<<it1.Key()<<" : "<<NbDisp<<endl;
#endif
}
#endif
Handle(AIS_InteractiveObject) curIO;
Handle(Standard_Transient) Tr;
for(TColStd_MapIteratorOfMapOfTransient it2(theMap);it2.More();it2.Next()){
@@ -816,11 +815,11 @@ void AIS_InteractiveContext::Remove(const Handle(AIS_InteractiveObject)& anIObj,
}
else
{
Standard_Boolean WasInCtx = myLocalContexts(myCurLocalIndex)->Remove(anIObj);
myLocalContexts(myCurLocalIndex)->Remove(anIObj);
AIS_DataMapIteratorOfDataMapOfILC It(myLocalContexts);
for (;It.More() ;It.Next()){
if(It.Value()->AcceptErase())
WasInCtx = It.Value()->Remove(anIObj);
It.Value()->Remove(anIObj);
}
// if(!WasInCtx)
@@ -2417,7 +2416,10 @@ void AIS_InteractiveContext::ClearGlobal(const Handle(AIS_InteractiveObject)& an
{
Handle(AIS_InteractiveObject) anObj = DetectedCurrentObject();
if( !anObj.IsNull() && anObj != anIObj )
{
myAISDetectedSeq.Remove( i );
myAISDetectedShapes.Remove(i);
}
}
if(myLastinMain == anIObj)

View File

@@ -51,6 +51,7 @@
#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <SelectMgr_Selection.hxx>
#include <SelectBasics_SensitiveEntity.hxx>
#include <StdSelect_BRepOwner.hxx>
#ifdef IMP150501
#include <Visual3d_TransientManager.hxx>
@@ -146,6 +147,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo(const Standard_Integer XPix
//Nullify class members storing information about detected AIS objects.
myAISCurDetected = 0;
myAISDetectedSeq.Clear();
myAISDetectedShapes.Clear();
#endif
// OCC11904 - local variables made non-static - it looks and works better like this
@@ -183,7 +185,16 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo(const Standard_Integer XPix
Handle(AIS_InteractiveObject) anObj =
Handle(AIS_InteractiveObject)::DownCast(anEntityOwner->Selectable());
if(!Handle(AIS_Shape)::DownCast(anObj).IsNull())
{
myAISDetectedSeq.Append(anObj);
// Memorize detected shape.
TopoDS_Shape detectedShape;
Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast(anEntityOwner);
if (!aBRepOwner.IsNull() && aBRepOwner->HasShape())
detectedShape = aBRepOwner->Shape();
myAISDetectedShapes.Append(detectedShape);
}
}
}
#endif
@@ -1418,7 +1429,11 @@ const TopoDS_Shape& AIS_InteractiveContext::DetectedCurrentShape() const
static TopoDS_Shape bidsh;
if(myAISCurDetected > 0 &&
myAISCurDetected <= myAISDetectedSeq.Length())
return Handle(AIS_Shape)::DownCast(myAISDetectedSeq(myAISCurDetected))->Shape();
{
if (myAISDetectedShapes(myAISCurDetected).IsNull())
return Handle(AIS_Shape)::DownCast(myAISDetectedSeq(myAISCurDetected))->Shape();
return myAISDetectedShapes(myAISCurDetected);
}
return bidsh;
}

View File

@@ -708,3 +708,33 @@ Standard_Boolean AIS_LengthDimension::InitOneShapePoints (const TopoDS_Shape& th
return IsValidPoints (myFirstPoint, mySecondPoint);
}
//=======================================================================
//function : GetTextPosition
//purpose :
//=======================================================================
const gp_Pnt AIS_LengthDimension::GetTextPosition () const
{
if (myIsTextPositionFixed)
{
return myFixedTextPosition;
}
// Counts text position according to the dimension parameters
return GetTextPositionForLinear (myFirstPoint, mySecondPoint);
}
//=======================================================================
//function : SetTextPosition
//purpose :
//=======================================================================
void AIS_LengthDimension::SetTextPosition (const gp_Pnt& theTextPos)
{
if (!myIsValid)
{
return;
}
SetTextPositionForLinear (myFirstPoint, mySecondPoint, theTextPos);
SetToUpdate();
}

View File

@@ -188,7 +188,7 @@ public:
//! @return the display units string.
Standard_EXPORT virtual const TCollection_AsciiString& GetDisplayUnits () const;
//! @return the model units string.
Standard_EXPORT virtual const TCollection_AsciiString& GetModelUnits () const;
@@ -196,6 +196,10 @@ public:
Standard_EXPORT virtual void SetModelUnits (const TCollection_AsciiString& theUnits);
Standard_EXPORT virtual void SetTextPosition (const gp_Pnt& theTextPos);
Standard_EXPORT virtual const gp_Pnt GetTextPosition () const;
public:
DEFINE_STANDARD_RTTI(AIS_LengthDimension)

View File

@@ -77,7 +77,8 @@ uses
LocalStatus from AIS,
StatusOfPick from AIS,
StatusOfDetection from AIS,
SequenceOfInteractive from AIS
SequenceOfInteractive from AIS,
SequenceOfShape from TopTools
is
@@ -629,6 +630,7 @@ fields
myAISCurDetected : Integer from Standard;
-- This variables is used by following functions:
-- InitDetected(), MoreDetected(), NextDetected(), DetectedCurrentShape(), DetectedCurrentObject().
myAISDetectedShapes : SequenceOfShape from TopTools;
friends

View File

@@ -445,7 +445,6 @@ Standard_Boolean AIS_LocalContext::Remove(const Handle(AIS_InteractiveObject)& a
const Handle(AIS_LocalStatus)& Att = myActiveObjects(aSelectable);
TColStd_ListIteratorOfListOfInteger It;
Standard_Boolean jobdone(Standard_False);
// it is checked which were the temporary attributes
// and they are set to 0
@@ -468,7 +467,6 @@ Standard_Boolean AIS_LocalContext::Remove(const Handle(AIS_InteractiveObject)& a
if(myMainPM->IsDisplayed(aSelectable,Att->HilightMode()))
myMainPM->Erase(aSelectable,Att->HilightMode());
// myMainPM->Clear(aSelectable,Att->HilightMode());
jobdone = Standard_True;
}
// if below intensity
else
@@ -505,7 +503,10 @@ Standard_Boolean AIS_LocalContext::Remove(const Handle(AIS_InteractiveObject)& a
{
Handle(AIS_InteractiveObject) anObj = DetectedCurrentObject();
if( !anObj.IsNull() && anObj != aSelectable )
{
myAISDetectedSeq.Remove( i );
myAISDetectedShapes.Remove( i );
}
}
Standard_Integer aHM = aSelectable->HasHilightMode() ? aSelectable->HilightMode() : 0;

View File

@@ -127,6 +127,7 @@ AIS_StatusOfDetection AIS_LocalContext::MoveTo(const Standard_Integer Xpix,
//Nullify class members storing information about detected AIS objects.
myAISCurDetected = 0;
myAISDetectedSeq.Clear();
myAISDetectedShapes.Clear();
#endif
myCurDetected = 0;
myDetectedSeq.Clear();
@@ -142,8 +143,20 @@ AIS_StatusOfDetection AIS_LocalContext::MoveTo(const Standard_Integer Xpix,
myDetectedSeq.Append(i_detect); // normallly they are already arranged in correct order...
#ifdef IMP160701
Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(EO->Selectable());
if(!Handle(AIS_Shape)::DownCast(anObj).IsNull())
Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast(anObj);
if(!aisShape.IsNull())
{
myAISDetectedSeq.Append(anObj);
// Memorize detected shape.
TopoDS_Shape detectedShape;
Handle(StdSelect_BRepOwner) BO = Handle(StdSelect_BRepOwner)::DownCast(EO);
if (!BO.IsNull() && BO->HasShape())
detectedShape = BO->Shape();
else if (!aisShape->Shape().IsNull())
detectedShape = aisShape->Shape();
myAISDetectedShapes.Append(detectedShape);
}
#endif
}
}
@@ -1017,7 +1030,9 @@ void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)&
}
}
if(EO.IsNull())
{
EO = new SelectMgr_EntityOwner(anIObj);
}
#ifndef OCC138
EO->State(1);
#endif
@@ -1596,7 +1611,11 @@ const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
{
static TopoDS_Shape bidsh;
if (MoreDetected())
return Handle(AIS_Shape)::DownCast(myAISDetectedSeq(myAISCurDetected))->Shape();
{
if (myAISDetectedShapes(myAISCurDetected).IsNull())
return Handle(AIS_Shape)::DownCast(myAISDetectedSeq(myAISCurDetected))->Shape();
return myAISDetectedShapes(myAISCurDetected);
}
return bidsh;
}

View File

@@ -262,3 +262,33 @@ Standard_Boolean AIS_RadiusDimension::IsValidAnchor (const gp_Circ& theCircle,
return Abs (anAnchorDist - aRadius) > Precision::Confusion()
&& aCirclePlane.Contains (theAnchor, Precision::Confusion());
}
//=======================================================================
//function : GetTextPosition
//purpose :
//=======================================================================
const gp_Pnt AIS_RadiusDimension::GetTextPosition () const
{
if (myIsTextPositionFixed)
{
return myFixedTextPosition;
}
// Counts text position according to the dimension parameters
return GetTextPositionForLinear (myAnchorPoint, myCircle.Location(), Standard_True);
}
//=======================================================================
//function : GetTextPosition
//purpose :
//=======================================================================
void AIS_RadiusDimension::SetTextPosition (const gp_Pnt& theTextPos)
{
if (!myIsValid)
{
return;
}
SetTextPositionForLinear (myAnchorPoint, myCircle.Location(), theTextPos);
SetToUpdate();
}

View File

@@ -50,7 +50,7 @@ public:
//! orientation by location of the first point on that circle.
//! @param theCircle [in] the circle to measure.
//! @param theAnchorPoint [in] the point to define the position
//! of the dimension attachement on the circle.
//! of the dimension attachment on the circle.
Standard_EXPORT AIS_RadiusDimension (const gp_Circ& theCircle,
const gp_Pnt& theAnchorPoint);
@@ -88,7 +88,7 @@ public:
//! Measure radius of the circle and orient the dimension so
//! the dimension lines attaches to anchor point on the circle.
//! The dimension will become invalid if the radiuss of the circle
//! The dimension will become invalid if the radius of the circle
//! is less than Precision::Confusion().
//! @param theCircle [in] the circle to measure.
//! @param theAnchorPoint [in] the point to attach the dimension lines.
@@ -111,6 +111,10 @@ public:
Standard_EXPORT virtual void SetModelUnits (const TCollection_AsciiString& theUnits);
Standard_EXPORT virtual void SetTextPosition (const gp_Pnt& theTextPos);
Standard_EXPORT virtual const gp_Pnt GetTextPosition () const;
public:
DEFINE_STANDARD_RTTI (AIS_RadiusDimension)

View File

@@ -464,7 +464,7 @@ void AIS_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
}
// insert the drawer in the BrepOwners for hilight...
StdSelect::SetDrawerForBRepOwner(aSelection,myDrawer);
// StdSelect::SetDrawerForBRepOwner(aSelection,myDrawer);
}
Quantity_NameOfColor AIS_Shape::Color() const {

View File

@@ -17,3 +17,4 @@ AIS_DiameterDimension.hxx
AIS_DiameterDimension.cxx
AIS_RadiusDimension.hxx
AIS_RadiusDimension.cxx
AIS_DimensionLayoutMode.hxx

View File

@@ -5,8 +5,8 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
@@ -234,11 +234,20 @@ static void UpdateCurves(BRep_ListOfCurveRepresentation& lcr,
Handle(BRep_CurveRepresentation) cr;
Handle(BRep_GCurve) GC;
Standard_Real f = 0.,l = 0.;
Standard_Boolean rangeFound = Standard_False;
while (itcr.More()) {
GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
if ( !GC.IsNull() ) {
GC->Range(f,l);
if (GC->IsCurve3D()) {
GC->Range(f,l);
Standard_Boolean undefined = (Precision::IsPositiveInfinite(l) ||
Precision::IsNegativeInfinite(f));
if (!undefined) {
rangeFound = Standard_True;
}
}
Standard_Boolean iscos = GC->IsCurveOnSurface(S,L);
if (iscos) break;
}
@@ -256,7 +265,7 @@ static void UpdateCurves(BRep_ListOfCurveRepresentation& lcr,
Handle(BRep_CurveOnClosedSurface) COS =
new BRep_CurveOnClosedSurface(C1,C2,S,L,GeomAbs_C0);
// test if there is already a range
if (!GC.IsNull()) {
if (rangeFound) {
COS->SetRange(f,l);
}
lcr.Append(COS);
@@ -281,11 +290,20 @@ static void UpdateCurves(BRep_ListOfCurveRepresentation& lcr,
Handle(BRep_CurveRepresentation) cr;
Handle(BRep_GCurve) GC;
Standard_Real f = 0.,l = 0.;
Standard_Boolean rangeFound = Standard_False;
while (itcr.More()) {
GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
if ( !GC.IsNull() ) {
GC->Range(f,l);
if (GC->IsCurve3D()) {
GC->Range(f,l);
Standard_Boolean undefined = (Precision::IsPositiveInfinite(l) ||
Precision::IsNegativeInfinite(f));
if (!undefined) {
rangeFound = Standard_True;
}
}
Standard_Boolean iscos = GC->IsCurveOnSurface(S,L);
if (iscos) break;
}
@@ -303,7 +321,7 @@ static void UpdateCurves(BRep_ListOfCurveRepresentation& lcr,
Handle(BRep_CurveOnClosedSurface) COS =
new BRep_CurveOnClosedSurface(C1,C2,S,L,GeomAbs_C0);
// test if there is already a range
if (!GC.IsNull()) {
if (rangeFound) {
COS->SetRange(f,l);
}
COS->SetUVPoints2(Pf,Pl);
@@ -546,7 +564,6 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C,l);
if (!C.IsNull()) TE->Closed(C->IsClosed());
TE->UpdateTolerance(Tol);
TE->Modified(Standard_True);
@@ -613,8 +630,6 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C1,C2,S,l);
if (!C1.IsNull() && !C2.IsNull())
TE->Closed(C1->IsClosed() && C2->IsClosed());
TE->UpdateTolerance(Tol);
TE->Modified(Standard_True);
@@ -639,9 +654,7 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C1,C2,S,l,Pf,Pl);
if (!C1.IsNull() && !C2.IsNull())
TE->Closed(C1->IsClosed() && C2->IsClosed());
TE->UpdateTolerance(Tol);
TE->Modified(Standard_True);
}
@@ -705,14 +718,14 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
while (itcr.More())
{
if (itcr.Value()->IsPolygonOnTriangulation(T,l))
{
{
// cr is used to keep a reference on the curve representation
// this avoid deleting it as its content may be referenced by T
cr = itcr.Value();
lcr.Remove(itcr);
isModified = Standard_True;
break;
}
}
itcr.Next();
}
@@ -996,23 +1009,8 @@ void BRep_Builder::Range(const TopoDS_Edge& E,
while (itcr.More()) {
GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
if (!GC.IsNull()) {
if (!Only3d || GC->IsCurve3D())
GC->SetRange(First,Last);
if (GC->IsCurve3D()) {
// Set the closedness flag to the correct value.
Handle(Geom_Curve) C = GC->Curve3D();
//fixing a bug PRO18577 to avoid infinite values of First and Last
if ( !C.IsNull() &&
!Precision::IsNegativeInfinite(First) &&
!Precision::IsPositiveInfinite(Last) ) {
Standard_Boolean closed =
C->Value(First).IsEqual(C->Value(Last),BRep_Tool::Tolerance(E));
TE->Closed(closed);
}
}
}
if (!GC.IsNull() && (!Only3d || GC->IsCurve3D()))
GC->SetRange(First,Last);
itcr.Next();
}
@@ -1040,20 +1038,10 @@ void BRep_Builder::Range(const TopoDS_Edge& E,
while (itcr.More()) {
GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
if (!GC.IsNull()) {
if (GC->IsCurveOnSurface(S,l)) {
GC->SetRange(First,Last);
// Set the closedness flag to the correct value.
Handle(Geom2d_Curve) PC = GC->PCurve();
gp_Pnt2d P1 = PC->Value(First);
gp_Pnt2d P2 = PC->Value(Last);
gp_Pnt PP1 = S->Value(P1.X(),P1.Y());
gp_Pnt PP2 = S->Value(P2.X(),P2.Y());
Standard_Boolean closed = PP1.IsEqual(PP2,BRep_Tool::Tolerance(E));
TE->Closed(closed);
break;
}
if (!GC.IsNull() && GC->IsCurveOnSurface(S,l))
{
GC->SetRange(First,Last);
break;
}
itcr.Next();
}
@@ -1076,7 +1064,7 @@ void BRep_Builder::Transfert(const TopoDS_Edge& Ein,
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Ein.TShape());
const Standard_Real tol = TE->Tolerance();
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);

View File

@@ -4,8 +4,8 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
@@ -16,22 +16,11 @@
#ifndef _BRepBuilderAPI_VertexInspector_Header
#define _BRepBuilderAPI_VertexInspector_Header
#ifndef _TColStd_ListOfInteger_HeaderFile
#include <TColStd_ListOfInteger.hxx>
#endif
#ifndef NCollection_Vector_HeaderFile
#include <NCollection_Vector.hxx>
#endif
#ifndef _gp_XY_HeaderFile
#include <gp_XY.hxx>
#endif
#ifndef _gp_XYZ_HeaderFile
#include <gp_XYZ.hxx>
#endif
#ifndef NCollection_CellFilter_HeaderFile
#include <NCollection_CellFilter.hxx>
#endif
typedef NCollection_Vector<gp_XYZ> VectorOfPoint;
@@ -48,8 +37,7 @@ class BRepBuilderAPI_VertexInspector : public NCollection_CellFilter_InspectorXY
public:
typedef Standard_Integer Target;
//! Constructor; remembers the tolerance
BRepBuilderAPI_VertexInspector (const Standard_Real theTol)
: myTol(theTol*theTol)
BRepBuilderAPI_VertexInspector (const Standard_Real theTol):myTol(theTol*theTol)
{}
//! Keep the points used for comparison
@@ -77,7 +65,7 @@ public:
}
//! Implementation of inspection method
NCollection_CellFilter_Action Inspect (const Standard_Integer theTarget);
Standard_EXPORT NCollection_CellFilter_Action Inspect (const Standard_Integer theTarget);
private:
Standard_Real myTol;

View File

@@ -5,8 +5,8 @@
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and / or modify it
-- under the terms of the GNU Lesser General Public version 2.1 as published
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
@@ -18,17 +18,22 @@ class OffsetWire from BRepFill
---Purpose: Constructs a Offset Wire to a spine (wire or face)
-- on the left of spine.
-- The Wire or the Face must be planar.
uses
Face from TopoDS,
Shape from TopoDS,
JoinType from GeomAbs,
ListOfShape from TopTools,
SequenceOfShape from TopTools,
SequenceOfPnt from TColgp,
DataMapOfShapeShape from TopTools,
IndexedDataMapOfOrientedShapeListOfShape from BRepFill,
DataMapOfOrientedShapeListOfShape from BRepFill,
BisectingLocus from BRepMAT2d,
LinkTopoBilo from BRepMAT2d
LinkTopoBilo from BRepMAT2d,
Bisec from Bisector,
TrimEdgeTool from BRepFill
raises
ConstructionError from Standard,
@@ -39,12 +44,14 @@ is
Create returns OffsetWire from BRepFill;
Create ( Spine : Face from TopoDS;
Join : JoinType from GeomAbs = GeomAbs_Arc)
Join : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean from Standard = Standard_False)
returns OffsetWire from BRepFill;
Init ( me : in out;
Spine : Face from TopoDS;
Join : JoinType from GeomAbs = GeomAbs_Arc)
Join : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean from Standard = Standard_False)
---Purpose: Initialize the evaluation of Offseting.
raises
ConstructionError from Standard
@@ -114,6 +121,16 @@ is
---Purpose: Add the OffsetWire <Other> to <me> and update <myMap>
is static private;
UpdateDetromp (me; Detromp : in out DataMapOfOrientedShapeListOfShape from BRepFill;
Shape1, Shape2 : Shape from TopoDS;
Vertices : SequenceOfShape from TopTools;
Params : SequenceOfPnt from TColgp;
Bisec : Bisec from Bisector;
SOnE : Boolean from Standard;
EOnE : Boolean from Standard;
Trim : TrimEdgeTool from BRepFill)
is static private;
MakeWires (me : in out)
---Purpose: Constructs the wires with the trimmed offset edges.
is static private;
@@ -127,6 +144,7 @@ fields
mySpine : Face from TopoDS;
myWorkSpine : Face from TopoDS;
myOffset : Real from Standard; -- >0 ;
myIsOpenResult : Boolean from Standard;
myShape : Shape from TopoDS;
myIsDone : Boolean from Standard;
myJoinType : JoinType from GeomAbs;

View File

@@ -5,8 +5,8 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
@@ -55,6 +55,7 @@
#include <GeomAPI.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Line.hxx>
#include <Geom_OffsetCurve.hxx>
#include <MAT_Arc.hxx>
#include <MAT_Node.hxx>
@@ -105,9 +106,6 @@
#include <DrawTrSurf.hxx>
#include <DrawTrSurf_Curve2d.hxx>
#include <DBRep.hxx>
#endif
#ifdef DEB
static Standard_Boolean AffichGeom = Standard_False;
static Standard_Boolean Affich2d = Standard_False;
static Standard_Boolean AffichEdge = Standard_False;
@@ -115,10 +113,6 @@ static Standard_Integer NbTRIMEDGES = 0;
static Standard_Integer NbOFFSET = 0;
static Standard_Integer NbEDGES = 0;
static Standard_Integer NbBISSEC = 0;
#ifndef WNT
static char tname[100];
static Standard_CString name = tname ;
#endif
#endif
// Modified by Sergey KHROMOV - Thu Nov 16 17:24:39 2000 Begin
@@ -174,15 +168,6 @@ static void EdgeVertices (const TopoDS_Edge& E,
}
}
static void UpdateDetromp (TopTools_ListOfShape& Detromp1,
TopTools_ListOfShape& Detromp2,
const TopTools_SequenceOfShape& Vertices,
const TColgp_SequenceOfPnt& Params,
const Bisector_Bisec& Bisec,
const Standard_Boolean SOnE,
const Standard_Boolean EOnE,
const BRepFill_TrimEdgeTool& Trim);
static Standard_Boolean VertexFromNode
(const Handle(MAT_Node)& aNode,
const Standard_Real Offset,
@@ -196,10 +181,11 @@ static void StoreInMap (const TopoDS_Shape& V1,
static void TrimEdge (const TopoDS_Edge& CurrentEdge,
const TopTools_ListOfShape& D,
TopTools_SequenceOfShape& Sv,
TColStd_SequenceOfReal& MapverPar,
TopTools_SequenceOfShape& S,
TopTools_IndexedDataMapOfShapeShape& MapVV);
TopTools_SequenceOfShape& Sv,
TColStd_SequenceOfReal& MapverPar,
TopTools_SequenceOfShape& S,
TopTools_IndexedDataMapOfShapeShape& MapVV,
const Standard_Integer IndOfE);
static Standard_Boolean DoubleOrNotInside (const TopTools_ListOfShape& EC,
const TopoDS_Vertex& V);
@@ -220,7 +206,9 @@ static void MakeOffset
const TopoDS_Face& F,
const Standard_Real Offset,
BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map,
const Handle(Geom_Plane)& RefPlane);
const Handle(Geom_Plane)& RefPlane,
const Standard_Boolean IsOpenResult,
const TopoDS_Vertex * Ends);
@@ -265,9 +253,6 @@ static Standard_Boolean KPartCircle
E = TopoDS::Edge(exp.Current());
if (NbEdges > 1) return Standard_False;
}
TopoDS_Vertex V1,V2;
TopExp::Vertices(E,V1,V2);
if (!V1.IsSame(V2)) return Standard_False;
Standard_Real f,l;
TopLoc_Location L;
@@ -278,15 +263,43 @@ static Standard_Boolean KPartCircle
C = Ct->BasisCurve();
}
if (!C->IsKind(STANDARD_TYPE(Geom_Circle))) return Standard_False;
Handle(Geom_Circle) CE = Handle(Geom_Circle)::DownCast(C);
Standard_Real anOffset = myOffset;
if (E.Orientation() == TopAbs_REVERSED) anOffset *= -1;
if (anOffset < 0. || Abs(anOffset) < CE->Radius()) {
Handle(Geom_Circle) OC = new Geom_Circle (CE->Position(),CE->Radius() - anOffset);
myShape = BRepLib_MakeEdge(OC,f,l);
TopoDS_Vertex V1,V2;
TopExp::Vertices(E,V1,V2);
if (!V1.IsSame(V2) || //open result or closed circle
C->IsKind(STANDARD_TYPE(Geom_Circle)))
{
Standard_Real anOffset = myOffset;
Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(E, mySpine, f, l);
Handle(Geom2dAdaptor_HCurve) AHC = new Geom2dAdaptor_HCurve(aPCurve, f, l);
Handle(Geom2d_Curve) OC;
if (AHC->GetType() == GeomAbs_Line)
{
if (E.Orientation() == TopAbs_REVERSED)
anOffset *= -1;
Adaptor3d_OffsetCurve Off(AHC,anOffset);
OC = new Geom2d_Line(Off.Line());
}
else if (AHC->GetType() == GeomAbs_Circle)
{
if (E.Orientation() == TopAbs_FORWARD)
anOffset *= -1;
gp_Circ2d theCirc = AHC->Circle();
if (anOffset < 0. || Abs(anOffset) < theCirc.Radius())
OC = new Geom2d_Circle (theCirc.Position(), theCirc.Radius() - anOffset);
}
else
{
if (E.Orientation() == TopAbs_FORWARD)
anOffset *= -1;
Handle(Geom2d_TrimmedCurve) G2dT = new Geom2d_TrimmedCurve(aPCurve, f, l);
OC = new Geom2d_OffsetCurve( G2dT, anOffset);
}
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(mySpine);
Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurf);
myShape = BRepLib_MakeEdge(OC, aPlane, f, l);
BRepLib::BuildCurve3d(TopoDS::Edge(myShape));
myShape.Orientation(E.Orientation());
myShape.Location(L);
if (Alt != 0.) {
@@ -298,13 +311,19 @@ static Standard_Boolean KPartCircle
T.SetTranslation(Trans);
myShape.Move(TopLoc_Location(T));
}
TopTools_ListOfShape LL;
LL.Append(myShape);
myMap.Add(E,LL);
TopoDS_Edge myEdge = TopoDS::Edge(myShape);
myShape = BRepLib_MakeWire(myEdge);
myIsDone = Standard_True;
return Standard_True;
}
myIsDone = Standard_True;
return Standard_True;
return Standard_False;
}
//=======================================================================
@@ -313,7 +332,8 @@ static Standard_Boolean KPartCircle
//=======================================================================
BRepFill_OffsetWire::BRepFill_OffsetWire()
:myIsDone(Standard_False)
: myIsOpenResult(Standard_False),
myIsDone(Standard_False)
{
}
@@ -324,9 +344,10 @@ BRepFill_OffsetWire::BRepFill_OffsetWire()
//=======================================================================
BRepFill_OffsetWire::BRepFill_OffsetWire(const TopoDS_Face& Spine,
const GeomAbs_JoinType Join )
const GeomAbs_JoinType Join,
const Standard_Boolean IsOpenResult)
{
Init(Spine,Join);
Init(Spine,Join,IsOpenResult);
}
//=======================================================================
@@ -335,16 +356,15 @@ BRepFill_OffsetWire::BRepFill_OffsetWire(const TopoDS_Face& Spine,
//=======================================================================
void BRepFill_OffsetWire::Init(const TopoDS_Face& Spine,
const GeomAbs_JoinType Join )
const GeomAbs_JoinType Join,
const Standard_Boolean IsOpenResult)
{
Standard_NotImplemented_Raise_if(Join > GeomAbs_Arc,
"Only GeomAbs_Arc is implemented");
myIsDone = Standard_False;
TopoDS_Shape aLocalShape = Spine.Oriented(TopAbs_FORWARD);
mySpine = TopoDS::Face(aLocalShape);
// mySpine = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD));
myJoinType = Join;
myIsOpenResult = IsOpenResult;
CheckFace(mySpine);
@@ -379,8 +399,8 @@ void BRepFill_OffsetWire::Init(const TopoDS_Face& Spine,
// static BRepMAT2d_Explorer Exp;
// Modified by Sergey KHROMOV - Tue Nov 26 17:39:03 2002 End
Exp.Perform(myWorkSpine);
myBilo.Compute(Exp,1,MAT_Left);
myLink.Perform(Exp,myBilo);
myBilo.Compute(Exp, 1 ,MAT_Left, myJoinType, myIsOpenResult);
myLink.Perform(Exp, myBilo);
}
@@ -500,7 +520,7 @@ void BRepFill_OffsetWire::Perform (const Standard_Real Offset,
{
OCC_CATCH_SIGNALS
myCallGen = Standard_False;
if (KPartCircle(mySpine,Offset,Alt,myShape,myMap,myIsDone)) return;
if (KPartCircle(myWorkSpine,Offset,Alt,myShape,myMap,myIsDone)) return;
TopoDS_Face oldWorkSpain = myWorkSpine;
@@ -602,14 +622,12 @@ void BRepFill_OffsetWire::Perform (const Standard_Real Offset,
if(aSubst.IsCopied(myWorkSpine)) {
myWorkSpine = TopoDS::Face(aSubst.Copy(myWorkSpine).First());
//sprintf(name,"WS1");
//DBRep::Set(name,myWorkSpine);
BRepMAT2d_Explorer newExp;
newExp.Perform(myWorkSpine);
BRepMAT2d_BisectingLocus newBilo;
BRepMAT2d_LinkTopoBilo newLink;
newBilo.Compute(newExp,1,MAT_Left);
newBilo.Compute(newExp, 1, MAT_Left, myJoinType, myIsOpenResult);
if(!newBilo.IsDone())
{
@@ -635,24 +653,29 @@ void BRepFill_OffsetWire::Perform (const Standard_Real Offset,
{
myShape.Nullify();
myIsDone = Standard_False;
#ifdef BREPFILL_DEB
cout<<"An exception was caught in BRepFill_OffsetWire::Perform : ";
Standard_Failure::Caught()->Print(cout);
cout<<endl;
#endif
return;
}
// Modified by skv - Fri Jul 8 11:21:38 2005 OCC9145 End
// Modified by Sergey KHROMOV - Thu Mar 14 10:48:15 2002 Begin
TopExp_Explorer anExp(myShape, TopAbs_WIRE);
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape &aWire = anExp.Current();
if (!aWire.Closed()) {
myShape.Nullify();
myIsDone = Standard_False;
Standard_ConstructionError::Raise("Offset wire is not closed.");
if (!myIsOpenResult)
{
TopExp_Explorer anExp(myShape, TopAbs_WIRE);
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape &aWire = anExp.Current();
if (!aWire.Closed()) {
myShape.Nullify();
myIsDone = Standard_False;
Standard_ConstructionError::Raise("Offset wire is not closed.");
}
}
}
// Modified by Sergey KHROMOV - Thu Mar 14 10:48:16 2002 End
@@ -706,9 +729,6 @@ void BRepFill_OffsetWire::PerformWithBiLo
const GeomAbs_JoinType Join,
const Standard_Real Alt)
{
Standard_NotImplemented_Raise_if (Join > GeomAbs_Arc,
"Only GeomAbs_Arc is implemented");
myIsDone = Standard_False;
TopoDS_Shape aLocalShape = Spine.Oriented(TopAbs_FORWARD);
myWorkSpine = TopoDS::Face(aLocalShape);
@@ -734,7 +754,7 @@ void BRepFill_OffsetWire::PerformWithBiLo
//********************************
// Calculate for a non null offset
//********************************
if (KPartCircle(mySpine,Offset,Alt,myShape,myMap,myIsDone))
if (KPartCircle(myWorkSpine,Offset,Alt,myShape,myMap,myIsDone))
return;
BRep_Builder myBuilder;
@@ -770,25 +790,36 @@ void BRepFill_OffsetWire::PerformWithBiLo
//---------------------------------------------------------------
// Construction of Circles and OffsetCurves
//---------------------------------------------------------------
TopoDS_Vertex Ends [2];
if (myIsOpenResult)
{
TopoDS_Wire theWire;
TopoDS_Iterator iter(mySpine);
theWire = TopoDS::Wire(iter.Value());
TopExp::Vertices(theWire, Ends[0], Ends[1]);
}
for (Standard_Integer ic = 1; ic <= Locus.NumberOfContours(); ic++) {
TopoDS_Shape PEE = Link.GeneratingShape(Locus.BasicElt(ic,Locus.NumberOfElts(ic)));
TopoDS_Shape& PE = PEE ;
for (Standard_Integer ie = 1; ie <= Locus.NumberOfElts(ic); ie++) {
const TopoDS_Shape& SE = Link.GeneratingShape(Locus.BasicElt(ic,ie));
if (SE.ShapeType() == TopAbs_VERTEX) {
MakeCircle (TopoDS::Edge(PE),TopoDS::Vertex(SE),
myWorkSpine,myOffset,myMap,RefPlane);
if (!SE.IsSame(Ends[0]) && !SE.IsSame(Ends[1]))
MakeCircle (TopoDS::Edge(PE),TopoDS::Vertex(SE),
myWorkSpine,myOffset,myMap,RefPlane);
}
else {
MakeOffset (TopoDS::Edge(SE),myWorkSpine,myOffset,myMap,RefPlane);
MakeOffset (TopoDS::Edge(SE),myWorkSpine,myOffset,myMap,RefPlane,
myIsOpenResult, Ends);
PE = SE;
}
}
}
#ifdef DEB
#ifdef DRAW
if (AffichEdge) {
cout << " End Construction of geometric primitives "<<endl;
}
@@ -816,6 +847,7 @@ void BRepFill_OffsetWire::PerformWithBiLo
#ifdef DRAW
if ( AffichGeom) {
char name[256];
sprintf(name,"BISSEC_%d",NbBISSEC++);
DrawTrSurf::Set(name,Bisec.Value());
}
@@ -930,7 +962,7 @@ void BRepFill_OffsetWire::PerformWithBiLo
if (!Detromp.IsBound(S[1])) Detromp.Bind(S[1],EmptyList);
UpdateDetromp (Detromp(S[0]), Detromp(S[1]), Vertices, Params,
UpdateDetromp (Detromp, S[0], S[1], Vertices, Params,
Bisec, StartOnEdge, EndOnEdge, Trim);
//----------------------------------------------
// Storage of vertices on parallel edges.
@@ -967,7 +999,7 @@ void BRepFill_OffsetWire::PerformWithBiLo
}
}
#ifdef DEB
#ifdef DRAW
if (AffichEdge) {
cout << " End Construction of vertices on offsets"<<endl;
}
@@ -990,11 +1022,19 @@ void BRepFill_OffsetWire::PerformWithBiLo
if (MapBis.IsBound(CurrentEdge)) {
TopTools_SequenceOfShape S;
if (!MapBis(CurrentEdge).IsEmpty()) {
Standard_Integer IndOfE = 0;
if (myIsOpenResult)
{
if (j == 1)
IndOfE = 1;
else if (j == myMap.Extent())
IndOfE = -1;
}
TrimEdge (CurrentEdge,
Detromp (CurrentSpine),
MapBis (CurrentEdge) ,
MapVerPar(CurrentEdge) ,
S, MapVV);
S, MapVV, IndOfE);
for ( k = 1; k <= S.Length(); k++) {
myMap(j).Append(S.Value(k));
}
@@ -1143,7 +1183,7 @@ void BRepFill_OffsetWire::PrepareSpine()
TopExp::MapShapes(IteF.Value(), TopAbs_EDGE, EdgeMap);
Standard_Integer nbEdges = EdgeMap.Extent();
if (nbEdges == 1)
if (nbEdges == 1 && !myIsOpenResult) //in case of open wire there's no need to do it
ForcedCut = 2;
// Modified by Sergey KHROMOV - Thu Nov 16 17:29:48 2000 End
@@ -1192,13 +1232,108 @@ void BRepFill_OffsetWire::PrepareSpine()
#ifdef DRAW
if ( AffichEdge) {
sprintf(name,"WS");
DBRep::Set(name,myWorkSpine);
DBRep::Set("WS",myWorkSpine);
}
#endif
}
//=======================================================================
//function : UpdateDetromp
//purpose : For each interval on bissectrice defined by parameters
// test if the medium point is at a distance > offset
// in this case vertices corresponding to the extremities of the interval
// are ranked in the proofing.
// => If the same vertex appears in the proofing, the
// border of the zone of proximity is tangent to the offset .
//=======================================================================
void BRepFill_OffsetWire::UpdateDetromp (BRepFill_DataMapOfOrientedShapeListOfShape& Detromp,
const TopoDS_Shape& Shape1,
const TopoDS_Shape& Shape2,
const TopTools_SequenceOfShape& Vertices,
const TColgp_SequenceOfPnt& Params,
const Bisector_Bisec& Bisec,
const Standard_Boolean SOnE,
const Standard_Boolean EOnE,
const BRepFill_TrimEdgeTool& Trim) const
{
if (myJoinType == GeomAbs_Intersection &&
Vertices.Length() == 1 &&
!EOnE)
{
TopTools_IndexedMapOfShape Vmap1, Vmap2;
TopExp::MapShapes(Shape1, TopAbs_VERTEX, Vmap1);
TopExp::MapShapes(Shape2, TopAbs_VERTEX, Vmap2);
Standard_Boolean Adjacent = Standard_False;
for (Standard_Integer i = 1; i <= Vmap1.Extent(); i++)
for (Standard_Integer j = 1; j <= Vmap2.Extent(); j++)
if (Vmap1(i).IsSame(Vmap2(j)))
{
Adjacent = Standard_True;
break;
}
if (Adjacent)
{
Detromp(Shape1).Append(Vertices.First());
Detromp(Shape2).Append(Vertices.First());
return;
}
}
Standard_Integer ii = 1;
Standard_Real U1,U2;
TopoDS_Vertex V1,V2;
Handle(Geom2d_Curve) Bis = Bisec.Value();
U1 = Bis->FirstParameter();
if (SOnE) {
// the first point of the bissectrice is on the offset
V1 = TopoDS::Vertex(Vertices.Value(ii));
ii++;
}
while (ii <= Vertices.Length()) {
U2 = Params.Value(ii).X();
V2 = TopoDS::Vertex(Vertices.Value(ii));
gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
if (!Trim.IsInside(P)) {
if (!V1.IsNull()) {
Detromp(Shape1).Append(V1);
Detromp(Shape2).Append(V1);
}
Detromp(Shape1).Append(V2);
Detromp(Shape2).Append(V2);
}
U1 = U2;
V1 = V2;
ii ++;
}
// test medium point between the last parameter and the end of the bissectrice.
U2 = Bis->LastParameter();
if (!EOnE) {
if (!Precision::IsInfinite(U2)) {
gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
if (!Trim.IsInside(P)) {
if (!V1.IsNull()) {
Detromp(Shape1).Append(V1);
Detromp(Shape2).Append(V1);
}
}
}
else {
if (!V1.IsNull()) {
Detromp(Shape1).Append(V1);
Detromp(Shape2).Append(V1);
}
}
}
}
//=======================================================================
//function : MakeWires
//purpose :
@@ -1825,6 +1960,7 @@ void MakeCircle (const TopoDS_Edge& E,
#ifdef DRAW
if ( AffichGeom && !OE.IsNull()) {
char name[256];
sprintf(name,"OFFSET_%d",++NbOFFSET);
DBRep::Set(name,OE);
}
@@ -1840,7 +1976,9 @@ void MakeOffset (const TopoDS_Edge& E,
const TopoDS_Face& F,
const Standard_Real Offset,
BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map,
const Handle(Geom_Plane)& RefPlane)
const Handle(Geom_Plane)& RefPlane,
const Standard_Boolean IsOpenResult,
const TopoDS_Vertex * Ends)
{
Standard_Real f,l;
Standard_Real anOffset = Offset;
@@ -1850,6 +1988,20 @@ void MakeOffset (const TopoDS_Edge& E,
Handle(Geom2d_Curve) G2d = BRep_Tool::CurveOnSurface(E,F,f,l);
Handle(Geom2d_Curve) G2dOC;
Standard_Boolean ToExtendFirstPar = Standard_True;
Standard_Boolean ToExtendLastPar = Standard_True;
if (IsOpenResult)
{
TopoDS_Vertex V1, V2;
TopExp::Vertices(E, V1, V2);
if (V1.IsSame(Ends[0]) ||
V1.IsSame(Ends[1]))
ToExtendFirstPar = Standard_False;
if (V2.IsSame(Ends[0]) ||
V2.IsSame(Ends[1]))
ToExtendLastPar = Standard_False;
}
Geom2dAdaptor_Curve AC(G2d,f,l);
if ( AC.GetType() == GeomAbs_Circle) {
// if the offset is greater otr equal to the radius and the side of the
@@ -1861,7 +2013,7 @@ void MakeOffset (const TopoDS_Edge& E,
Standard_Real Crossed = Xd.X()*Yd.Y()-Xd.Y()*Yd.X();
Standard_Real Signe = ( Crossed > 0.) ? 1. : -1.;
if (anOffset*Signe < AC.Circle().Radius()) {
if (anOffset*Signe < AC.Circle().Radius() - Precision::Confusion()) {
Handle(Geom2dAdaptor_HCurve) AHC =
new Geom2dAdaptor_HCurve(G2d);
@@ -1869,7 +2021,10 @@ void MakeOffset (const TopoDS_Edge& E,
Handle(Geom2d_Circle) CC = new Geom2d_Circle(Off.Circle());
Standard_Real Delta = 2*M_PI - l + f;
f -= 0.2*Delta; l += 0.2*Delta;
if (ToExtendFirstPar)
f -= 0.2*Delta;
if (ToExtendLastPar)
l += 0.2*Delta;
G2dOC = new Geom2d_TrimmedCurve(CC,f,l);
}
@@ -1880,7 +2035,10 @@ void MakeOffset (const TopoDS_Edge& E,
Adaptor3d_OffsetCurve Off(AHC,anOffset);
Handle(Geom2d_Line) CC = new Geom2d_Line(Off.Line());
Standard_Real Delta = (l - f);
f -= Delta; l += Delta;
if (ToExtendFirstPar)
f -= Delta;
if (ToExtendLastPar)
l += Delta;
G2dOC = new Geom2d_TrimmedCurve(CC,f,l);
}
else {
@@ -1901,6 +2059,7 @@ void MakeOffset (const TopoDS_Edge& E,
#ifdef DRAW
if (AffichGeom && !OE.IsNull()) {
char name[256];
sprintf(name,"OFFSET_%d",++NbOFFSET);
DBRep::Set(name,OE);
Standard_Real ii = 0;
@@ -1910,77 +2069,6 @@ void MakeOffset (const TopoDS_Edge& E,
}
}
//=======================================================================
//function : UpdateDetromp
//purpose : For each interval on bissectrice defined by parameters
// test if the medium point is at a distance > offset
// in this case vertices corresponding to the extremities of the interval
// are ranked in the proofing.
// => If the same vertex appears in the proofing, the
// border of the zone of proximity is tangent to the offset .
//=======================================================================
void UpdateDetromp (TopTools_ListOfShape& Detromp1,
TopTools_ListOfShape& Detromp2,
const TopTools_SequenceOfShape& Vertices,
const TColgp_SequenceOfPnt& Params,
const Bisector_Bisec& Bisec,
const Standard_Boolean SOnE,
const Standard_Boolean EOnE,
const BRepFill_TrimEdgeTool& Trim)
{
Standard_Integer ii = 1;
Standard_Real U1,U2;
TopoDS_Vertex V1,V2;
Handle(Geom2d_Curve) Bis = Bisec.Value();
U1 = Bis->FirstParameter();
if (SOnE) {
// the first point of the bissectrice is on the offset
V1 = TopoDS::Vertex(Vertices.Value(ii));
ii++;
}
while (ii <= Vertices.Length()) {
U2 = Params.Value(ii).X();
V2 = TopoDS::Vertex(Vertices.Value(ii));
gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
if (!Trim.IsInside(P)) {
if (!V1.IsNull()) {
Detromp1.Append(V1);
Detromp2.Append(V1);
}
Detromp1.Append(V2);
Detromp2.Append(V2);
}
U1 = U2;
V1 = V2;
ii ++;
}
// test medium point between the last parameter and the end of the bissectrice.
U2 = Bis->LastParameter();
if (!EOnE) {
if (!Precision::IsInfinite(U2)) {
gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
if (!Trim.IsInside(P)) {
if (!V1.IsNull()) {
Detromp1.Append(V1);
Detromp2.Append(V1);
}
}
}
else {
if (!V1.IsNull()) {
Detromp1.Append(V1);
Detromp2.Append(V1);
}
}
}
}
//=======================================================================
//function : VertexFromNode
@@ -2050,10 +2138,11 @@ void StoreInMap (const TopoDS_Shape& V1,
void TrimEdge (const TopoDS_Edge& E,
const TopTools_ListOfShape& Detromp,
TopTools_SequenceOfShape& TheVer,
TColStd_SequenceOfReal& ThePar,
TopTools_SequenceOfShape& S,
TopTools_IndexedDataMapOfShapeShape& MapVV)
TopTools_SequenceOfShape& TheVer,
TColStd_SequenceOfReal& ThePar,
TopTools_SequenceOfShape& S,
TopTools_IndexedDataMapOfShapeShape& MapVV,
const Standard_Integer IndOfE)
{
Standard_Boolean Change = Standard_True;
BRep_Builder TheBuilder;
@@ -2124,45 +2213,94 @@ void TrimEdge (const TopoDS_Edge& E,
// the number of vertices should be even. The created edges
// go from a vertex with uneven index i to vertex i+1;
//-----------------------------------------------------------
for (Standard_Integer k = 1; k < TheVer.Length(); k = k+2) {
if (IndOfE == 1 || IndOfE == -1) //open result and extreme edges of result
{
TopoDS_Shape aLocalShape = E.EmptyCopied();
TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
// TopoDS_Edge NewEdge = TopoDS::Edge(E.EmptyCopied());
if (NewEdge.Orientation() == TopAbs_REVERSED) {
TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_REVERSED));
TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_FORWARD));
TopoDS_Vertex V1, V2;
TopExp::Vertices(E, V1, V2);
Standard_Real fpar, lpar;
BRep_Tool::Range(E, fpar, lpar);
if (IndOfE == 1) //first edge of open wire
{
if (NewEdge.Orientation() == TopAbs_FORWARD)
{
TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_FORWARD));
TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED));
TheBuilder.Range(NewEdge, fpar, ThePar.First());
}
else
{
//TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_REVERSED));
//TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD));
TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED));
TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_FORWARD));
TheBuilder.Range(NewEdge, ThePar.First(), lpar);
}
}
else {
TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_FORWARD));
TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_REVERSED));
else //last edge of open wire
{
if (NewEdge.Orientation() == TopAbs_FORWARD)
{
TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD));
TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_REVERSED));
TheBuilder.Range(NewEdge, ThePar.First(), lpar);
}
else
{
//TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED));
//TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_FORWARD));
TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_REVERSED));
TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD));
TheBuilder.Range(NewEdge, fpar, ThePar.First());
}
}
TheBuilder.Range(NewEdge,ThePar.Value(k),ThePar.Value(k+1));
#ifdef DRAW
if ( AffichEdge) {
sprintf(name,"TRIMEDGE_%d",NbTRIMEDGES);
DBRep::Set(name,NewEdge);
}
if (Affich2d) {
TopLoc_Location L;
Standard_Real f,l;
Handle(Geom_Surface) Surf;
Handle(Geom2d_Curve) C;
BRep_Tool::CurveOnSurface(NewEdge,C,Surf,L,f,l);
sprintf(name,"OFFSET2d_%d",NbTRIMEDGES++);
Handle(Geom2d_TrimmedCurve) C2d = new Geom2d_TrimmedCurve(C,f,l);
Handle(DrawTrSurf_Curve2d) dr =
new DrawTrSurf_Curve2d(C2d,Standard_False);
dr->SetColor(Draw_bleu);
Draw::Set(name,dr);
}
#endif
S.Append(NewEdge);
}
else
{
for (Standard_Integer k = 1; k < TheVer.Length(); k = k+2) {
TopoDS_Shape aLocalShape = E.EmptyCopied();
TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
// TopoDS_Edge NewEdge = TopoDS::Edge(E.EmptyCopied());
if (NewEdge.Orientation() == TopAbs_REVERSED) {
TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_REVERSED));
TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_FORWARD));
}
else {
TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_FORWARD));
TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_REVERSED));
}
TheBuilder.Range(NewEdge,ThePar.Value(k),ThePar.Value(k+1));
#ifdef DRAW
if ( AffichEdge) {
char name[256];
sprintf(name,"TRIMEDGE_%d",NbTRIMEDGES);
DBRep::Set(name,NewEdge);
}
if (Affich2d) {
TopLoc_Location L;
Standard_Real f,l;
Handle(Geom_Surface) Surf;
Handle(Geom2d_Curve) C;
BRep_Tool::CurveOnSurface(NewEdge,C,Surf,L,f,l);
char name[256];
sprintf(name,"OFFSET2d_%d",NbTRIMEDGES++);
Handle(Geom2d_TrimmedCurve) C2d = new Geom2d_TrimmedCurve(C,f,l);
Handle(DrawTrSurf_Curve2d) dr =
new DrawTrSurf_Curve2d(C2d,Standard_False);
dr->SetColor(Draw_bleu);
Draw::Set(name,dr);
}
#endif
S.Append(NewEdge);
}
}
}
//=======================================================================

View File

@@ -686,7 +686,8 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
// 1) Preparation
Prepare();
if (myStatus != GeomFill_PipeOk) {
if (myStatus != GeomFill_PipeOk ||
!mySection->NbLaw()) {
BRep_Builder B;
TopoDS_Shell Sh;
B.MakeShell(Sh);

View File

@@ -44,6 +44,8 @@
//=======================================================================
Standard_Integer BRepFill_SectionLaw::NbLaw() const
{
if (myLaws.IsNull())
return 0;
return myLaws->Length();
}

View File

@@ -1437,13 +1437,17 @@ static TopoDS_Edge BuildEdge(const Handle(Geom_Surface)& S,
// Associate 2d
Handle(Geom2d_Line) L;
TopLoc_Location Loc;
Standard_Real Umin, Umax, Vmin, Vmax;
S->Bounds(Umin, Umax, Vmin, Vmax);
if (isUiso) {
gp_Pnt2d P(ValIso, 0);
//gp_Pnt2d P(ValIso, 0);
gp_Pnt2d P( ValIso, Vmin - Iso->FirstParameter() );
gp_Vec2d V(0., 1.);
L = new (Geom2d_Line) (P, V);
}
else {
gp_Pnt2d P(0., ValIso);
//gp_Pnt2d P(0., ValIso);
gp_Pnt2d P( Umin -Iso->FirstParameter() , ValIso );
gp_Vec2d V(1., 0.);
L = new (Geom2d_Line) (P, V);
}

View File

@@ -5,8 +5,8 @@
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and / or modify it
-- under the terms of the GNU Lesser General Public version 2.1 as published
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
@@ -19,6 +19,7 @@ package BRepMAT2d
---Purpose:
uses
GeomAbs,
MAT2d,
MAT,
TCollection,
@@ -27,29 +28,20 @@ uses
Geom2d,
gp,
TopoDS,
TopTools
TopTools,
Bisector
is
class Explorer;
---Purpose: Construct an explorer for the computation of the
-- bisecting locus from a Wire, a Face, or a set of
-- curves from Geom2d.
class BisectingLocus instantiates BisectingLocus from MAT2d
(Explorer from BRepMAT2d);
---Purpose: the map of bisecting locus.
class BisectingLocus;
class LinkTopoBilo;
---Purpose: Constucts links between the Wire or the Face and
-- the BasicElts contained in the bisecting locus.
class SequenceOfBasicElt instantiates Sequence from TCollection
(BasicElt from MAT);
class DataMapOfShapeSequenceOfBasicElt instantiates DataMap from TCollection
(Shape from TopoDS,
SequenceOfBasicElt from BRepMAT2d,
SequenceOfBasicElt from MAT,
ShapeMapHasher from TopTools);
class DataMapOfBasicEltShape instantiates

View File

@@ -0,0 +1,166 @@
-- Created on: 1993-07-06
-- Created by: Yves FRICAUD
-- Copyright (c) 1993-1999 Matra Datavision
-- Copyright (c) 1999-2014 OPEN CASCADE SAS
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
--
-- Alternatively, this file may be used under the terms of Open CASCADE
-- commercial license or contractual agreement.
class BisectingLocus from BRepMAT2d
---Purpose : BisectingLocus generates and contains the Bisecting_Locus
-- of a set of lines from Geom2d, defined by <ExploSet>.
--
-- If the set of lines contains closed lines:
-- ------------------------------------------
-- These lines cut the plane in areas.
-- One map can be computed for each area.
--
-- Bisecting locus computes a map in an area.
-- The area is defined by a side (MAT_Left,MAT_Right)
-- on one of the closed lines.
--
-- If the set of lines contains only open lines:
-- --------------------------------------------
-- the map recovers all the plane.
--
-- Warning: Assume the orientation of the closed lines are
-- compatible.
--
-- Assume the explo contains only lines located in the
-- area where the bisecting locus will be computed.
--
-- Assume a line don't cross itself or an other line.
--
-- Remark:
-- the curves coming from the explorer can be
-- decomposed in different parts. It the case for the
-- curves other than circles or lines.
--
-- The map of bisecting locus is described by a graph.
-- - The BasicsElements correspond to elements on
-- the figure described by the Explorer from BRepMAT2d.
-- - The Arcs correspond to the bisectors.
-- - The Nodes are the extremities of the arcs.
uses
JoinType from GeomAbs,
Graph from MAT,
Arc from MAT,
BasicElt from MAT,
Node from MAT,
Side from MAT,
DataMapOfIntegerBasicElt from MAT,
DataMapOfBiIntInteger from MAT2d,
Bisec from Bisector,
Geometry from Geom2d,
Pnt2d from gp,
Tool2d from MAT2d,
Explorer from BRepMAT2d
is
Create returns BisectingLocus from BRepMAT2d;
---Category: Construction.
Compute (me : in out ;
anExplo : in out Explorer from BRepMAT2d;
LineIndex : Integer = 1;
aSide : Side from MAT = MAT_Left;
aJoinType : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean = Standard_False)
--- Purpose : Computation of the Bisector_Locus in a set of Lines
-- defined in <anExplo>.
-- The bisecting locus are computed on the side <aSide>
-- from the line <LineIndex> in <anExplo>.
is static;
---Category: Querying.
IsDone (me) returns Boolean from Standard
---Purpose: Returns True if Compute has succeeded.
is static;
Graph(me) returns Graph from MAT
--- Purpose : Returns <theGraph> of <me>.
is static;
NumberOfContours (me)
---Purpose: Returns the number of contours.
returns Integer from Standard
is static;
NumberOfElts( me ; IndLine : Integer)
---Purpose: Returns the number of BasicElts on the line
-- <IndLine>.
returns Integer from Standard
is static;
NumberOfSections (me; IndLine : Integer; Index : Integer)
---Purpose: Returns the number of sections of a curve.
-- this curve is the Indexth curve in the IndLineth contour
-- given by anExplo.
--
returns Integer from Standard
is static;
BasicElt ( me ; IndLine : Integer ; Index : Integer)
---Purpose: Returns the BasicElts located at the position
-- <Index> on the contour designed by <IndLine>.
-- Remark: the BasicElts on a contour are sorted.
--
returns BasicElt from MAT
is static;
GeomElt(me ; aBasicElt : BasicElt from MAT)
--- Purpose : Returns the geometry linked to the <BasicElt>.
returns Geometry from Geom2d
is static;
GeomElt(me ; aNode : Node from MAT)
--- Purpose : Returns the geometry of type <gp> linked to
-- the <Node>.
returns Pnt2d from gp
is static;
GeomBis(me ; anArc : Arc from MAT ; Reverse :in out Boolean from Standard)
--- Purpose : Returns the geometry of type <Bissec>
-- linked to the arc <ARC>.
-- <Reverse> is False when the FirstNode of <anArc>
-- correspond to the first point of geometry.
--
returns Bisec from Bisector
is static;
---Category: private methods.
Fusion(me : in out)
is static private;
RenumerationAndFusion
(me : in out;
IndexLine : Integer;
LengthLine : Integer;
IndexLast : in out Integer;
NewMap : in out DataMapOfIntegerBasicElt from MAT)
is static private;
fields
theGraph : Graph from MAT;
theTool : Tool2d from MAT2d;
isDone : Boolean from Standard;
nbSect : DataMapOfBiIntInteger from MAT2d;
nbContours : Integer from Standard;
end BisectingLocus;

View File

@@ -0,0 +1,348 @@
// Created on: 1993-07-13
// Created by: Yves FRICAUD
// Copyright (c) 1993-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
# include <BRepMAT2d_BisectingLocus.ixx>
# include <MAT2d_Mat2d.hxx>
# include <MAT2d_Tool2d.hxx>
# include <MAT2d_Circuit.hxx>
# include <MAT2d_CutCurve.hxx>
# include <MAT2d_BiInt.hxx>
# include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
# include <MAT_Graph.hxx>
# include <MAT_Arc.hxx>
# include <MAT_BasicElt.hxx>
# include <MAT_Node.hxx>
# include <MAT_Bisector.hxx>
# include <MAT_ListOfBisector.hxx>
# include <MAT_DataMapOfIntegerBasicElt.hxx>
# include <MAT_DataMapIteratorOfDataMapOfIntegerBasicElt.hxx>
# include <Geom2d_Curve.hxx>
# include <gp_Pnt2d.hxx>
# include <TColGeom2d_SequenceOfGeometry.hxx>
# include <Precision.hxx>
#include <Standard_OutOfRange.hxx>
static void CutSketch (MAT2d_SequenceOfSequenceOfGeometry& Figure,
MAT2d_DataMapOfBiIntInteger& NbSect);
//=============================================================================
//function : BRepMAT2d_BisectingLocus
//purpose : Constructeur vide.
//=============================================================================
BRepMAT2d_BisectingLocus::BRepMAT2d_BisectingLocus()
{
}
//=============================================================================
//function : Compute
//purpose : Calcul de la carte des lieux bisecteurs sur le contour defini par
// <anExplo>.
//=============================================================================
void BRepMAT2d_BisectingLocus::Compute(BRepMAT2d_Explorer& anExplo,
const Standard_Integer IndexLine,
const MAT_Side aSide,
const GeomAbs_JoinType aJoinType,
const Standard_Boolean IsOpenResult)
{
MAT2d_Mat2d TheMAT( IsOpenResult );
Handle(MAT_ListOfBisector) TheRoots = new MAT_ListOfBisector();
MAT2d_SequenceOfSequenceOfGeometry Figure;
Standard_Integer i;
nbSect.Clear();
nbContours = anExplo.NumberOfContours();
//---------------------------------
// Lecture des donnees de anExplo.
//---------------------------------
for (i = 1; i <= anExplo.NumberOfContours(); i++) {
TColGeom2d_SequenceOfGeometry Line;
Figure.Append(Line);
for (anExplo.Init(i); anExplo.More(); anExplo.Next()) {
Figure.ChangeValue(i).Append(anExplo.Value());
}
}
//-----------------------
// Decoupage des courbes.
//-----------------------
CutSketch(Figure,nbSect);
//----------------------------------------------------------
// Construction du circuit sur lequel est calcule la carte.
//----------------------------------------------------------
Handle(MAT2d_Circuit) ACircuit = new MAT2d_Circuit(aJoinType, IsOpenResult);
// Modified by Sergey KHROMOV - Wed Mar 6 17:43:47 2002 Begin
// ACircuit->Perform(Figure,IndexLine,(aSide == MAT_Left));
ACircuit->Perform(Figure,anExplo.GetIsClosed(), IndexLine,(aSide == MAT_Left));
// Modified by Sergey KHROMOV - Wed Mar 6 17:43:48 2002 End
// -----------------------
// Initialistion du Tool.
// -----------------------
theTool.Sense(aSide);
theTool.SetJoinType(aJoinType);
theTool.InitItems(ACircuit);
// --------------------------------------------
// Initialisation et execution de l algorithme.
// --------------------------------------------
if (IsOpenResult)
TheMAT.CreateMatOpen(theTool);
else
TheMAT.CreateMat(theTool);
isDone = TheMAT.IsDone(); if (!isDone) return;
// ----------------------------------------------------------------
// Recuperation du resultat de l algorithme et creation du graphe.
// ----------------------------------------------------------------
for (TheMAT.Init(); TheMAT.More(); TheMAT.Next()) {
TheRoots->BackAdd(TheMAT.Bisector());
}
theGraph = new MAT_Graph();
theGraph->Perform(TheMAT.SemiInfinite(),
TheRoots,
theTool.NumberOfItems(),
TheMAT.NumberOfBisectors());
//-----------------------------------------------------------------------
// Fusion des elements de base doubles si plusieurs lignes dans Exploset.
//-----------------------------------------------------------------------
if (anExplo.NumberOfContours() > 1) {
MAT_DataMapOfIntegerBasicElt NewMap;
Standard_Integer IndexLast = 1;
//-----------------------------------------------------------------------
// Construction de NewMap dont les elements sont ordonnes suivant les
// lignes du contour et qui ne contient pas d element dupliques.
// em meme temps fusion des arcs dupliques et mise a jour des noeuds.
//-----------------------------------------------------------------------
for ( i = 1; i <= anExplo.NumberOfContours(); i++) {
RenumerationAndFusion(i,
theTool.Circuit()->LineLength(i),
IndexLast,
NewMap);
}
//-----------------------------------------------------------------------
// Chargement dans le graph de la nouvelle map.
// et compactage de la map des Arcs (ie Elimination des trous du a la
// fusion d arcs ).et de celle des Nodes.
//-----------------------------------------------------------------------
theGraph->ChangeBasicElts(NewMap);
theGraph->CompactArcs();
theGraph->CompactNodes();
}
}
//=============================================================================
//function : RenumerationAndFusion
//purpose :
//=============================================================================
void BRepMAT2d_BisectingLocus::RenumerationAndFusion
(const Standard_Integer ILine,
const Standard_Integer LengthLine,
Standard_Integer& IndexLast,
MAT_DataMapOfIntegerBasicElt& NewMap)
{
Standard_Integer IndFirst;
Standard_Integer i,j;
Standard_Integer GeomIndexArc1,GeomIndexArc2,GeomIndexArc3,GeomIndexArc4;
Standard_Boolean MergeArc1,MergeArc2;
for ( i = 1; i <= LengthLine; i++) {
const TColStd_SequenceOfInteger& S = theTool.Circuit()->RefToEqui(ILine,i);
IndFirst = S.Value(1);
NewMap.Bind(IndexLast,theGraph->ChangeBasicElt(IndFirst));
IndexLast++;
for(j = 2; j <= S.Length(); j++){
theGraph->FusionOfBasicElts(IndFirst,
S.Value(j),
MergeArc1,
GeomIndexArc1,
GeomIndexArc2,
MergeArc2,
GeomIndexArc3,
GeomIndexArc4);
if(MergeArc1) {
theTool.BisecFusion(GeomIndexArc1,GeomIndexArc2);
}
if(MergeArc2) {
theTool.BisecFusion(GeomIndexArc3,GeomIndexArc4);
}
}
}
}
//=============================================================================
//function : IsDone
//Purpose :
//=============================================================================
Standard_Boolean BRepMAT2d_BisectingLocus::IsDone() const
{
return isDone;
}
//=============================================================================
//function : Graph
//
//=============================================================================
Handle(MAT_Graph) BRepMAT2d_BisectingLocus::Graph() const
{
return theGraph;
}
//=============================================================================
//function : NumberOfContours
//
//=============================================================================
Standard_Integer BRepMAT2d_BisectingLocus::NumberOfContours () const
{
return nbContours;
}
//=============================================================================
//function : NumberOfElts
//
//=============================================================================
Standard_Integer BRepMAT2d_BisectingLocus::NumberOfElts
(const Standard_Integer IndLine) const
{
return theTool.Circuit()->LineLength(IndLine);
}
//=============================================================================
//function : NumberOfSect
//
//=============================================================================
Standard_Integer BRepMAT2d_BisectingLocus::NumberOfSections
(const Standard_Integer IndLine,
const Standard_Integer Index )
const
{
MAT2d_BiInt B(IndLine,Index);
return nbSect(B);
}
//=============================================================================
//function : BasicElt
//
//=============================================================================
Handle(MAT_BasicElt) BRepMAT2d_BisectingLocus::BasicElt
(const Standard_Integer IndLine,
const Standard_Integer Index )
const
{
Standard_Integer i;
Standard_Integer Ind = Index;
for (i = 1 ; i < IndLine ; i++){
Ind = Ind + theTool.Circuit()->LineLength(i);
}
return theGraph->BasicElt(Ind);
}
//=============================================================================
//function : GeomBis
//
//=============================================================================
Bisector_Bisec BRepMAT2d_BisectingLocus::GeomBis (const Handle(MAT_Arc)& anArc,
Standard_Boolean& Reverse)
const
{
Reverse = Standard_False;
Handle(Geom2d_Curve) Bis = theTool.GeomBis(anArc->GeomIndex()).Value();
if (Bis->FirstParameter() <= -Precision::Infinite()) {
Reverse = Standard_True;
}
else if (Bis->LastParameter() < Precision::Infinite()) {
gp_Pnt2d PF = Bis->Value(Bis->FirstParameter());
gp_Pnt2d PL = Bis->Value(Bis->LastParameter());
gp_Pnt2d PNode = GeomElt(anArc->FirstNode());
if (PNode.SquareDistance(PF) > PNode.SquareDistance(PL))
Reverse = Standard_True;
}
return theTool.GeomBis(anArc->GeomIndex());
}
//=============================================================================
//function : GeomElt
//
//=============================================================================
Handle(Geom2d_Geometry) BRepMAT2d_BisectingLocus::GeomElt
(const Handle(MAT_BasicElt)& aBasicElt) const
{
return theTool.GeomElt(aBasicElt->GeomIndex());
}
//=============================================================================
//function : GeomElt
//
//=============================================================================
gp_Pnt2d BRepMAT2d_BisectingLocus::GeomElt(const Handle(MAT_Node)& aNode) const
{
return theTool.GeomPnt(aNode->GeomIndex());
}
//=============================================================================
//function : CutSketch
//
//=============================================================================
static void CutSketch (MAT2d_SequenceOfSequenceOfGeometry& Figure,
MAT2d_DataMapOfBiIntInteger& NbSect)
{
MAT2d_CutCurve Cuter;
Standard_Integer i,j,k,ico;
Standard_Integer ICurveInit;
Standard_Integer NbSection;
for ( i = 1; i <= Figure.Length(); i++) {
TColGeom2d_SequenceOfGeometry& Contour = Figure.ChangeValue(i);
ICurveInit = 0;
for ( j = 1; j <= Contour.Length(); j++) {
ICurveInit++;
Cuter.Perform(Handle(Geom2d_Curve)::DownCast(Contour.ChangeValue(j)));
NbSection = 1;
if (!Cuter.UnModified()) {
ico = j;
NbSection = Cuter.NbCurves();
for ( k = 1; k <= NbSection; k++) {
Contour.InsertAfter(j,Cuter.Value(k));
j++;
}
Contour.Remove(ico);
j--;
}
MAT2d_BiInt B(i,ICurveInit);
NbSect.Bind(B,NbSection);
}
}
}

View File

@@ -30,7 +30,7 @@
#include <MAT_Graph.hxx>
#include <MAT_BasicElt.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <BRepMAT2d_SequenceOfBasicElt.hxx>
#include <MAT_SequenceOfBasicElt.hxx>
#include <BRepMAT2d_DataMapOfShapeSequenceOfBasicElt.hxx>
#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
#include <TColStd_DataMapOfIntegerInteger.hxx>
@@ -170,7 +170,7 @@ void BRepMAT2d_LinkTopoBilo::LinkToWire(const TopoDS_Wire& W,
Handle(MAT_BasicElt) BE;
Handle(Standard_Type) Type;
TopTools_SequenceOfShape TopoSeq;
BRepMAT2d_SequenceOfBasicElt EmptySeq;
MAT_SequenceOfBasicElt EmptySeq;
TColStd_DataMapIteratorOfDataMapOfIntegerInteger Ite;
TColStd_DataMapOfIntegerInteger LinkBECont;

View File

@@ -40,13 +40,15 @@ is
Create returns MakeOffset from BRepOffsetAPI;
---Purpose: Constructs an algorithm for creating an empty offset
Create( Spine : Face from TopoDS;
Join : JoinType from GeomAbs = GeomAbs_Arc)
Join : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean from Standard = Standard_False)
returns MakeOffset from BRepOffsetAPI;
---Purpose: Constructs an algorithm for creating an algorithm
-- to build parallels to the spine Spine
Init( me : in out;
Spine : Face from TopoDS;
Join : JoinType from GeomAbs = GeomAbs_Arc)
Join : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean from Standard = Standard_False)
---Purpose: Initializes the algorithm to construct parallels to the spine Spine.
-- Join defines the type of parallel generated by the
-- salient vertices of the spine. The default type is
@@ -55,11 +57,13 @@ is
is static;
Create( Spine : Wire from TopoDS;
Join : JoinType from GeomAbs = GeomAbs_Arc)
Join : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean from Standard = Standard_False)
returns MakeOffset from BRepOffsetAPI;
Init( me : in out;
Join : JoinType from GeomAbs = GeomAbs_Arc)
Join : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean from Standard = Standard_False)
---Purpose: Initialize the evaluation of Offseting.
is static;
@@ -99,6 +103,7 @@ fields
myIsInitialized : Boolean from Standard;
myLastIsLeft : Boolean from Standard;
myJoin : JoinType from GeomAbs;
myIsOpenResult : Boolean from Standard;
myFace : Face from TopoDS;
myWires : ListOfShape from TopTools;
myLeft : ListOfOffsetWire from BRepFill;

View File

@@ -54,9 +54,10 @@ BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset()
//=======================================================================
BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Face& Spine,
const GeomAbs_JoinType Join)
const GeomAbs_JoinType Join,
const Standard_Boolean IsOpenResult)
{
Init(Spine, Join);
Init(Spine, Join, IsOpenResult);
}
@@ -66,11 +67,13 @@ BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Face& Spine,
//=======================================================================
void BRepOffsetAPI_MakeOffset::Init(const TopoDS_Face& Spine,
const GeomAbs_JoinType Join)
const GeomAbs_JoinType Join,
const Standard_Boolean IsOpenResult)
{
myFace = Spine;
myIsInitialized = Standard_True;
myJoin = Join;
myIsOpenResult = IsOpenResult;
TopExp_Explorer exp;
for (exp.Init(myFace,TopAbs_WIRE); exp.More();exp.Next()) {
myWires.Append(exp.Current());
@@ -83,11 +86,13 @@ void BRepOffsetAPI_MakeOffset::Init(const TopoDS_Face& Spine,
//=======================================================================
BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Wire& Spine,
const GeomAbs_JoinType Join)
const GeomAbs_JoinType Join,
const Standard_Boolean IsOpenResult)
{
myWires.Append(Spine);
myIsInitialized = Standard_True;
myJoin = Join;
myIsOpenResult = IsOpenResult;
}
//=======================================================================
@@ -95,9 +100,11 @@ BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Wire& Spine,
//purpose :
//=======================================================================
void BRepOffsetAPI_MakeOffset::Init(const GeomAbs_JoinType Join)
void BRepOffsetAPI_MakeOffset::Init(const GeomAbs_JoinType Join,
const Standard_Boolean IsOpenResult)
{
myJoin = Join;
myIsOpenResult = IsOpenResult;
}
//=======================================================================
@@ -118,10 +125,11 @@ void BRepOffsetAPI_MakeOffset::AddWire(const TopoDS_Wire& Spine)
//=======================================================================
static void BuildDomains(TopoDS_Face& myFace,
TopTools_ListOfShape& WorkWires,
BRepFill_ListOfOffsetWire& myAlgos,
GeomAbs_JoinType myJoin,
Standard_Boolean isPositive)
TopTools_ListOfShape& WorkWires,
BRepFill_ListOfOffsetWire& myAlgos,
GeomAbs_JoinType myJoin,
Standard_Boolean myIsOpenResult,
Standard_Boolean isPositive)
{
BRepAlgo_FaceRestrictor FR;
TopoDS_Vertex VF,VL;
@@ -190,7 +198,7 @@ static void BuildDomains(TopoDS_Face& myFace,
for ( ; itW.More(); itW.Next()) {
B.Add(F,itW.Value());
}
BRepFill_OffsetWire Algo(F, myJoin);
BRepFill_OffsetWire Algo(F, myJoin, myIsOpenResult);
myAlgos.Append(Algo);
return;
}
@@ -243,7 +251,7 @@ static void BuildDomains(TopoDS_Face& myFace,
// Creation of algorithms on each domain.
//========================================
for (itF.Initialize(Faces); itF.More(); itF.Next()) {
BRepFill_OffsetWire Algo(TopoDS::Face(itF.Value()), myJoin);
BRepFill_OffsetWire Algo(TopoDS::Face(itF.Value()), myJoin, myIsOpenResult);
myAlgos.Append(Algo);
}
}
@@ -253,13 +261,13 @@ static void BuildDomains(TopoDS_Face& myFace,
//purpose :
//=======================================================================
void BRepOffsetAPI_MakeOffset::Perform( const Standard_Real Offset,
const Standard_Real Alt)
void BRepOffsetAPI_MakeOffset::Perform(const Standard_Real Offset,
const Standard_Real Alt)
{
StdFail_NotDone_Raise_if ( !myIsInitialized,
"BRepOffsetAPI_MakeOffset : Perform without Init");
try
//try
{
Standard_Integer i = 1;
BRepFill_ListIteratorOfListOfOffsetWire itOW;
@@ -273,7 +281,7 @@ void BRepOffsetAPI_MakeOffset::Perform( const Standard_Real Offset,
if( myLeft.IsEmpty() )
{
// Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 Begin
BuildDomains(myFace,myWires,myLeft,myJoin, Standard_False);
BuildDomains(myFace,myWires,myLeft,myJoin,myIsOpenResult, Standard_False);
// Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 End
}
@@ -296,7 +304,7 @@ void BRepOffsetAPI_MakeOffset::Perform( const Standard_Real Offset,
if (myRight.IsEmpty())
{
// Modified by Sergey KHROMOV - Fri Apr 27 14:35:28 2001 Begin
BuildDomains(myFace,myWires,myRight,myJoin, Standard_True);
BuildDomains(myFace,myWires,myRight,myJoin,myIsOpenResult, Standard_True);
// Modified by Sergey KHROMOV - Fri Apr 27 14:35:35 2001 End
}
@@ -325,14 +333,14 @@ void BRepOffsetAPI_MakeOffset::Perform( const Standard_Real Offset,
else
Done();
}
catch(...) //Every exception was caught.
{
cout<<"An exception was caught in BRepOffsetAPI_MakeOffset::Perform : ";
Standard_ConstructionError::Caught()->Print(cout);
cout<<endl;
NotDone();
myShape.Nullify();
}
//catch(...) //Every exception was caught.
//{
// cout<<"An exception was caught in BRepOffsetAPI_MakeOffset::Perform : ";
// Standard_ConstructionError::Caught()->Print(cout);
// cout<<endl;
// NotDone();
// myShape.Nullify();
//}
}
//=======================================================================

View File

@@ -105,7 +105,7 @@
//=======================================================================
static Standard_Real PreciseUpar(const Standard_Real anUpar,
const Handle(Geom_BSplineSurface)& aSurface)
const Handle(Geom_BSplineSurface)& aSurface)
{
Standard_Real Tol = Precision::PConfusion();
Standard_Integer i1, i2;
@@ -126,17 +126,17 @@ static Standard_Real PreciseUpar(const Standard_Real anUpar,
//=======================================================================
static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
const Standard_Real presPln,
TopoDS_Face& theFace)
const Standard_Real presPln,
TopoDS_Face& theFace)
{
Standard_Boolean isDegen = Standard_True;
TopoDS_Iterator iter(W);
for (; iter.More(); iter.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
if (!BRep_Tool::Degenerated(anEdge))
isDegen = Standard_False;
}
{
const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
if (!BRep_Tool::Degenerated(anEdge))
isDegen = Standard_False;
}
if (isDegen)
return Standard_True;
@@ -144,22 +144,22 @@ static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
if (!W.IsNull()) {
BRepBuilderAPI_FindPlane Searcher( W, presPln );
if (Searcher.Found())
{
theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
Ok = Standard_True;
}
{
theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
Ok = Standard_True;
}
else // try to find another surface
{
BRepBuilderAPI_MakeFace MF( W );
if (MF.IsDone())
{
BRepBuilderAPI_MakeFace MF( W );
if (MF.IsDone())
{
theFace = MF.Face();
Ok = Standard_True;
}
theFace = MF.Face();
Ok = Standard_True;
}
}
}
return Ok;
return Ok;
}
//=============================================================================
@@ -168,7 +168,7 @@ static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
//=============================================================================
static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
const TopoDS_Shape& aShell)
const TopoDS_Shape& aShell)
{
TopExp_Explorer Explo(aFace, TopAbs_EDGE);
TopoDS_Shape anEdge = Explo.Current();
@@ -180,11 +180,11 @@ static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
TopoDS_Shape theEdge;
for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
{
theEdge = Explo.Current();
if (theEdge.IsSame(anEdge))
break;
}
{
theEdge = Explo.Current();
if (theEdge.IsSame(anEdge))
break;
}
TopAbs_Orientation Or2 = theEdge.Orientation();
if (Or1 == Or2)
@@ -198,8 +198,8 @@ static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
//=======================================================================
static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
const TopoDS_Wire& wire2, const Standard_Real presPln,
TopoDS_Face& face1, TopoDS_Face& face2)
const TopoDS_Wire& wire2, const Standard_Real presPln,
TopoDS_Face& face1, TopoDS_Face& face2)
{
if (shell.IsNull())
StdFail_NotDone::Raise("Thrusections is not build");
@@ -207,31 +207,31 @@ static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
BRep_Builder BB;
if (!B)
{
// It is necessary to close the extremities
B = PerformPlan(wire1, presPln, face1);
{
// It is necessary to close the extremities
B = PerformPlan(wire1, presPln, face1);
if (B) {
B = PerformPlan(wire2, presPln, face2);
if (B) {
B = PerformPlan(wire2, presPln, face2);
if (B) {
if (!face1.IsNull() && !IsSameOriented( face1, shell ))
face1.Reverse();
if (!face2.IsNull() && !IsSameOriented( face2, shell ))
face2.Reverse();
if (!face1.IsNull())
BB.Add(shell, face1);
if (!face2.IsNull())
BB.Add(shell, face2);
shell.Closed(Standard_True);
}
if (!face1.IsNull() && !IsSameOriented( face1, shell ))
face1.Reverse();
if (!face2.IsNull() && !IsSameOriented( face2, shell ))
face2.Reverse();
if (!face1.IsNull())
BB.Add(shell, face1);
if (!face2.IsNull())
BB.Add(shell, face2);
shell.Closed(Standard_True);
}
}
}
TopoDS_Solid solid;
BB.MakeSolid(solid);
BB.Add(solid, shell);
// verify the orientation the solid
BRepClass3d_SolidClassifier clas3d(solid);
clas3d.PerformInfinitePoint(Precision::Confusion());
@@ -239,7 +239,7 @@ static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
BB.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
BB.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(newShell.Reversed()));
// B.Add(solid, TopoDS::Shell(newShell.Reversed()));
}
solid.Closed(Standard_True);
@@ -253,11 +253,11 @@ static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
//=======================================================================
BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, const Standard_Boolean ruled,
const Standard_Real pres3d):
myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
const Standard_Real pres3d):
myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
{
myWCheck = Standard_True;
//----------------------------
//----------------------------
myParamType = Approx_ChordLength;
myDegMax = 8;
myContinuity = GeomAbs_C2;
@@ -274,13 +274,13 @@ BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean is
//=======================================================================
void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled,
const Standard_Real pres3d)
const Standard_Real pres3d)
{
myIsSolid = isSolid;
myIsRuled = ruled;
myPres3d = pres3d;
myWCheck = Standard_True;
//----------------------------
//----------------------------
myParamType = Approx_ChordLength;
myDegMax = 6;
myContinuity = GeomAbs_C2;
@@ -348,39 +348,39 @@ void BRepOffsetAPI_ThruSections::Build()
Standard_Integer i;
TopExp_Explorer explo;
for (i = 2; i <= myWires.Length()-1; i++)
{
Standard_Boolean wdeg = Standard_True;
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
Standard_Boolean wdeg = Standard_True;
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
Standard_Failure::Raise("Wrong usage of punctual sections");
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
Standard_Failure::Raise("Wrong usage of punctual sections");
}
if (myWires.Length() <= 2)
{
Standard_Boolean wdeg = Standard_True;
for (i = 1; i <= myWires.Length(); i++)
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
{
Standard_Boolean wdeg = Standard_True;
for (i = 1; i <= myWires.Length(); i++)
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
Standard_Failure::Raise("Wrong usage of punctual sections");
}
Standard_Failure::Raise("Wrong usage of punctual sections");
}
if (myWCheck) {
// compute origin and orientation on wires to avoid twisted results
// and update wires to have same number of edges
// use BRepFill_CompatibleWires
TopTools_SequenceOfShape WorkingSections;
WorkingSections.Clear();
TopTools_DataMapOfShapeListOfShape WorkingMap;
WorkingMap.Clear();
// Calculate the working sections
BRepFill_CompatibleWires Georges(myWires);
Georges.Perform();
@@ -402,7 +402,7 @@ void BRepOffsetAPI_ThruSections::Build()
}
// Encode the Regularities
BRepLib::EncodeRegularity(myShape);
}
@@ -415,7 +415,7 @@ void BRepOffsetAPI_ThruSections::CreateRuled()
{
Standard_Integer nbSects = myWires.Length();
BRepFill_Generator aGene;
// for (Standard_Integer i=1; i<=nbSects; i++) {
// for (Standard_Integer i=1; i<=nbSects; i++) {
Standard_Integer i;
for (i=1; i<=nbSects; i++) {
aGene.AddWire(TopoDS::Wire(myWires(i)));
@@ -434,15 +434,15 @@ void BRepOffsetAPI_ThruSections::CreateRuled()
BRep_Builder B;
B.MakeSolid(solid);
B.Add(solid, shell);
// verify the orientation of the solid
BRepClass3d_SolidClassifier clas3d(solid);
clas3d.PerformInfinitePoint(Precision::Confusion());
if (clas3d.State() == TopAbs_IN) {
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
}
myShape = solid;
@@ -472,12 +472,12 @@ void BRepOffsetAPI_ThruSections::CreateRuled()
TopTools_IndexedDataMapOfShapeListOfShape MV;
TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV);
for (i=1; i<=nbSects-1; i++) {
const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i));
const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1));
anExp1.Init(wire1);
anExp2.Init(wire2);
@@ -489,51 +489,51 @@ void BRepOffsetAPI_ThruSections::CreateRuled()
const TopoDS_Shape& edge2 = anExp2.Current();
Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current());
Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current());
TopTools_MapOfShape MapFaces;
if (degen2){
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
}
else {
for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
}
if (degen1) {
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
}
else {
for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
}
if (!degen1) anExp1.Next();
if (!degen2) anExp2.Next();
tantque = anExp1.More() && anExp2.More();
if (degen1) tantque = anExp2.More();
if (degen2) tantque = anExp1.More();
}
}
}
//=======================================================================
@@ -593,15 +593,15 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
// if the wire is punctual
anExp.Init(TopoDS::Wire(wire));
for(j=1; j<=nbEdges; j++) {
nb++;
shapes(nb) = anExp.Current();
nb++;
shapes(nb) = anExp.Current();
}
}
else {
// otherwise
for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
nb++;
shapes(nb) = anExp.Current();
nb++;
shapes(nb) = anExp.Current();
}
}
}
@@ -624,7 +624,6 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
TopLoc_Location loc;
TopoDS_Vertex v1f,v1l,v2f,v2l;
GeomFill_SectionGenerator section;
Standard_Integer nbPnts = 21;
TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects);
@@ -668,17 +667,17 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
// make the wire
B.MakeWire(W);
// make the missing edges
Standard_Real f1, f2, l1, l2;
surface->Bounds(f1,l1,f2,l2);
// --- edge 1
if ( w1Point ) {
// copy the degenerated edge
TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
edge1 = TopoDS::Edge(aLocalShape);
// edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
// edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
edge1.Orientation(TopAbs_FORWARD);
}
else {
@@ -693,21 +692,21 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
// store edges of the 1st section
if (vClosed)
vcouture(i) = edge1;
// --- edge 2
if (vClosed)
edge2 = TopoDS::Edge(vcouture(i));
else {
if ( w2Point ) {
// copy of the degenerated edge
TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
edge2 = TopoDS::Edge(aLocalShape);
// edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
edge2.Orientation(TopAbs_FORWARD);
// copy of the degenerated edge
TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
edge2 = TopoDS::Edge(aLocalShape);
// edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
edge2.Orientation(TopAbs_FORWARD);
}
else {
B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
}
v2f.Orientation(TopAbs_FORWARD);
B.Add(edge2, v2f);
@@ -727,7 +726,7 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
B.Add(edge3, v2f);
B.Range(edge3, f2, l2);
if (uClosed) {
couture = edge3;
couture = edge3;
}
}
else {
@@ -756,34 +755,34 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
// set PCurve
if (vClosed) {
B.UpdateEdge(edge1,
new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
Precision::Confusion());
new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
Precision::Confusion());
B.Range(edge1,face,f1,l1);
}
else {
B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge1,face,f1,l1);
B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge2,face,f1,l1);
}
if ( uClosed && nbEdges ==1 ) {
B.UpdateEdge(edge3,
new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
B.Range(edge3,face,f2,l2);
}
else {
B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge3,face,f2,l2);
B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge4,face,f2,l2);
}
B.Add(face,W);
@@ -812,15 +811,15 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
BRep_Builder B;
B.MakeSolid(solid);
B.Add(solid, shell);
// verify the orientation the solid
BRepClass3d_SolidClassifier clas3d(solid);
clas3d.PerformInfinitePoint(Precision::Confusion());
if (clas3d.State() == TopAbs_IN) {
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
}
myShape = solid;
@@ -837,7 +836,7 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
myShape = shell;
Done();
}
TopExp_Explorer ex(myShape,TopAbs_EDGE);
while (ex.More()) {
const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current());
@@ -855,12 +854,12 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
//=======================================================================
Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
TotalSurf(const TopTools_Array1OfShape& shapes,
const Standard_Integer NbSects,
const Standard_Integer NbEdges,
const Standard_Boolean w1Point,
const Standard_Boolean w2Point,
const Standard_Boolean vClosed) const
TotalSurf(const TopTools_Array1OfShape& shapes,
const Standard_Integer NbSects,
const Standard_Integer NbEdges,
const Standard_Boolean w1Point,
const Standard_Boolean w2Point,
const Standard_Boolean vClosed) const
{
Standard_Integer i,j,jdeb=1,jfin=NbSects;
TopoDS_Edge edge;
@@ -908,95 +907,96 @@ Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
// read the first edge to initialise CompBS;
edge = TopoDS::Edge(shapes((j-1)*NbEdges+1));
if (BRep_Tool::Degenerated(edge)) {
// degenerated edge : construction of a punctual curve
TopExp::Vertices(edge,vl,vf);
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = BRep_Tool::Pnt(vf);
Extremities(2) = BRep_Tool::Pnt(vl);
Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
curvTrim = new Geom_TrimmedCurve(curv,
curv->FirstParameter(),
curv->LastParameter());
// degenerated edge : construction of a punctual curve
TopExp::Vertices(edge,vl,vf);
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = BRep_Tool::Pnt(vf);
Extremities(2) = BRep_Tool::Pnt(vl);
Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
curvTrim = new Geom_TrimmedCurve(curv,
curv->FirstParameter(),
curv->LastParameter());
}
else {
// recover the curve on the edge
Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
curvTrim = new Geom_TrimmedCurve(curv, first, last);
curvTrim->Transform(loc.Transformation());
// recover the curve on the edge
Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
curvTrim = new Geom_TrimmedCurve(curv, first, last);
curvTrim->Transform(loc.Transformation());
}
if (edge.Orientation() == TopAbs_REVERSED) {
curvTrim->Reverse();
curvTrim->Reverse();
}
// transformation into BSpline reparameterized on [i-1,i]
curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
if (curvBS.IsNull()) {
Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
{
GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (appr.HasResult())
curvBS = appr.Curve();
}
if (curvBS.IsNull())
curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
{
GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (appr.HasResult())
curvBS = appr.Curve();
}
if (curvBS.IsNull())
curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
}
TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
curvBS->Knots(BSK);
BSplCLib::Reparametrize(0.,1.,BSK);
curvBS->SetKnots(BSK);
// initialization
GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
for (i=2; i<=NbEdges; i++) {
// read the edge
edge = TopoDS::Edge(shapes((j-1)*NbEdges+i));
if (BRep_Tool::Degenerated(edge)) {
// degenerated edge : construction of a punctual curve
TopExp::Vertices(edge,vl,vf);
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = BRep_Tool::Pnt(vf);
Extremities(2) = BRep_Tool::Pnt(vl);
Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
curvTrim = new Geom_TrimmedCurve(curv,
curv->FirstParameter(),
curv->LastParameter());
}
else {
// return the curve on the edge
Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
curvTrim = new Geom_TrimmedCurve(curv, first, last);
curvTrim->Transform(loc.Transformation());
}
if (edge.Orientation() == TopAbs_REVERSED) {
curvTrim->Reverse();
}
// read the edge
edge = TopoDS::Edge(shapes((j-1)*NbEdges+i));
Standard_Real aTolV = Precision::Confusion();
TopExp::Vertices(edge,vf,vl);
aTolV = Max(aTolV, BRep_Tool::Tolerance(vf));
aTolV = Max(aTolV, BRep_Tool::Tolerance(vl));
aTolV = Min(aTolV, 1.e-3);
if (BRep_Tool::Degenerated(edge)) {
// degenerated edge : construction of a punctual curve
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = BRep_Tool::Pnt(vf);
Extremities(2) = BRep_Tool::Pnt(vl);
Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
curvTrim = new Geom_TrimmedCurve(curv,
curv->FirstParameter(),
curv->LastParameter());
}
else {
// return the curve on the edge
Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
curvTrim = new Geom_TrimmedCurve(curv, first, last);
curvTrim->Transform(loc.Transformation());
}
if (edge.Orientation() == TopAbs_REVERSED) {
curvTrim->Reverse();
}
// transformation into BSpline reparameterized on [i-1,i]
curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
if (curvBS.IsNull()) {
Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
{
GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (appr.HasResult())
curvBS = appr.Curve();
}
if (curvBS.IsNull())
curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
}
TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
curvBS->Knots(BSK);
BSplCLib::Reparametrize(i-1,i,BSK);
curvBS->SetKnots(BSK);
// transformation into BSpline reparameterized on [i-1,i]
curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
if (curvBS.IsNull()) {
Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
{
GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (appr.HasResult())
curvBS = appr.Curve();
}
if (curvBS.IsNull())
curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
}
TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
curvBS->Knots(BSK);
BSplCLib::Reparametrize(i-1,i,BSK);
curvBS->SetKnots(BSK);
// concatenation
CompBS.Add(curvBS,
Precision::Confusion(),
Standard_True,
Standard_False,
1);
// concatenation
CompBS.Add(curvBS, aTolV, Standard_True, Standard_False, 1);
}
// return the final section
@@ -1005,7 +1005,7 @@ Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
// case of looping sections
if (j==jdeb && vClosed) {
BS1 = BS;
BS1 = BS;
}
}
@@ -1053,13 +1053,13 @@ Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
if(anApprox.IsDone()) {
surface =
new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
anApprox.SurfUKnots(), anApprox.SurfVKnots(),
anApprox.SurfUMults(), anApprox.SurfVMults(),
anApprox.UDegree(), anApprox.VDegree());
anApprox.SurfUKnots(), anApprox.SurfVKnots(),
anApprox.SurfUMults(), anApprox.SurfVMults(),
anApprox.UDegree(), anApprox.VDegree());
}
return surface;
}
//=======================================================================

View File

@@ -5,8 +5,8 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
@@ -20,6 +20,7 @@
#include <BRepToIGES_BRShell.ixx>
#include <BRepToIGES_BRWire.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
@@ -33,6 +34,7 @@
#include <Geom_Surface.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <Geom2d_Curve.hxx>
#include <GeomToIGES_GeomSurface.hxx>
@@ -47,10 +49,15 @@
#include <Interface_Macros.hxx>
#include <NCollection_Map.hxx>
#include <NCollection_IncAllocator.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
@@ -132,6 +139,74 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
if ( start.IsNull()) {
return res;
}
// pour explorer la face , il faut la mettre fORWARD.
TopoDS_Face myface;
if (start.Orientation() == TopAbs_REVERSED) {
//create face with redirected surface
BRep_Builder B;
TopLoc_Location aLoc;
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(start, aLoc);
aSurf = aSurf->UReversed();
Standard_Real U1, U2, V1, V2;
aSurf->Bounds(U1, U2, V1, V2);
Standard_Real aTol = BRep_Tool::Tolerance(start);
B.MakeFace(myface, aSurf, aLoc ,aTol);
// set specifics flags of a Face
B.NaturalRestriction(myface, BRep_Tool::NaturalRestriction(start));
//add wires
TopoDS_Wire anOuter = TopoDS::Wire(ShapeAlgo::AlgoContainer()->OuterWire(start));
TopExp_Explorer ex;
for (ex.Init(start,TopAbs_WIRE); ex.More(); ex.Next()) {
TopoDS_Wire W = TopoDS::Wire(ex.Current());
if (!W.IsNull() && W.IsSame(anOuter)) {
B.Add(myface, W);
break;
}
}
for (ex.Init(start,TopAbs_WIRE); ex.More(); ex.Next()) {
TopoDS_Wire W = TopoDS::Wire(ex.Current());
if (!W.IsNull() && !W.IsSame(anOuter)) {
B.Add(myface, W);
}
}
// mirror pcurves
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
for (ex.Init(myface,TopAbs_EDGE);ex.More(); ex.Next()) {
TopoDS_Edge anEdge = TopoDS::Edge(ex.Current());
if (!aMap.Add(anEdge))
// seam edge has been already updated
continue;
Standard_Real f, l;
Handle(Geom2d_Curve) aCurve1, aCurve2;
aCurve1 = BRep_Tool::CurveOnSurface(anEdge, start, f, l);
aTol = BRep_Tool::Tolerance(anEdge);
gp_Trsf2d T;
gp_Ax2d axis(gp_Pnt2d(0.5 * (U1 + U2), V1), gp_Dir2d(0.,1.));
T.SetMirror(axis);
if (!aCurve1.IsNull()) {
aCurve1 = Handle(Geom2d_Curve)::DownCast(aCurve1->Transformed(T));
if (BRepTools::IsReallyClosed(anEdge, start)) {
TopoDS_Edge revEdge = TopoDS::Edge(anEdge.Reversed());
aCurve2 = BRep_Tool::CurveOnSurface(revEdge, start, f, l);
if (!aCurve2.IsNull()) {
aCurve2 = Handle(Geom2d_Curve)::DownCast(aCurve2->Transformed(T));
B.UpdateEdge(anEdge, aCurve1, aCurve2, myface, aTol);
}
else {
B.UpdateEdge(anEdge, aCurve1, myface, aTol);
}
}
else {
B.UpdateEdge(anEdge, aCurve1, myface, aTol);
}
}
}
}
else {
myface = start;
}
//Standard_Integer Nb = 0; //szv#4:S4163:12Mar99 unused
Standard_Real Length = 1.;
Handle(IGESData_IGESEntity) ISurf;
@@ -139,13 +214,13 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
// returns the face surface
// ------------------------
Handle(Geom_Surface) Surf = BRep_Tool::Surface(start);
Handle(Geom_Surface) Surf = BRep_Tool::Surface(myface);
Handle(Geom_Surface) Surf1;
if (!Surf.IsNull()) {
Standard_Real U1, U2, V1, V2;
// pour limiter les surfaces de base
BRepTools::UVBounds(start, U1, U2, V1, V2);
BRepTools::UVBounds(myface, U1, U2, V1, V2);
GeomToIGES_GeomSurface GS;
GS.SetModel(GetModel());
ISurf = GS.TransferSurface(Surf, U1, U2, V1, V2);
@@ -172,16 +247,9 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
Standard_Integer Imode = 0;
Standard_Integer Iprefer = 0;
Handle(IGESData_IGESEntity) ICurve2d;
// pour explorer la face , il faut la mettre fORWARD.
TopoDS_Face myface = start;
Standard_Boolean IsReversed = Standard_False;
if (start.Orientation() == TopAbs_REVERSED) {
myface.Reverse();
IsReversed = Standard_True;
}
// outer wire
//:n3 TopoDS_Wire Outer = BRepTools::OuterWire(myface);
//:n3 TopoDS_Wire Outer = BRepTools::OuterWire(myface);
TopoDS_Wire Outer = ShapeAlgo::AlgoContainer()->OuterWire(myface); //:n3
Handle(IGESGeom_CurveOnSurface) IOuter = new IGESGeom_CurveOnSurface;
if (!Outer.IsNull()) {
@@ -205,7 +273,7 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
}
else if (!W.IsSame(Outer)) {
Handle(IGESData_IGESEntity) ICurve3d =
BW.TransferWire(W, myface, ICurve2d, Length);
BW.TransferWire(W, myface, ICurve2d, Length);
if ((!ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 3;
if ((!ICurve3d.IsNull()) && (ICurve2d.IsNull())) Iprefer = 2;
if ((ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 1;
@@ -256,10 +324,7 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
TrimmedSurf-> Init (ISurf, Flag, IOuter, Tab);
res = TrimmedSurf;
if (IsReversed) myface.Reverse();
SetShapeResult ( start, res );
return res;
}

View File

@@ -32,6 +32,7 @@
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_CartesianPoint.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_Curve.hxx>
@@ -64,6 +65,8 @@
#include <Precision.hxx>
#include <ShapeAnalysis.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
#include <TopoDS.hxx>
@@ -390,6 +393,25 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferEdge (const TopoDS_Edge&
}
else Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Copy());
//shift pcurves on periodic BSpline surfaces (issue 26138)
if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
Handle(Geom_BSplineSurface) aBSpline = Handle(Geom_BSplineSurface)::DownCast(Surf);
Standard_Real uShift = 0., vShift = 0.;
Standard_Real U0, U1, V0, V1;
Surf->Bounds(U0, U1, V0, V1);
if (aBSpline->IsUPeriodic() && Abs(Ufirst - U0) > Precision::PConfusion()) {
uShift = ShapeAnalysis::AdjustToPeriod(Ufirst, U0, U1);
}
if (aBSpline->IsVPeriodic() && Abs(Vfirst - V0) > Precision::PConfusion()) {
vShift = ShapeAnalysis::AdjustToPeriod(Vfirst, V0, V1);
}
if (Abs(uShift) > Precision::PConfusion() || Abs(vShift) > Precision::PConfusion()) {
gp_Trsf2d TR;
TR.SetTranslation(gp_Pnt2d(0.,0.),gp_Pnt2d(uShift,vShift));
Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Transformed(TR));
}
}
if (!analyticMode&&((Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) ||
(Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) ||
(Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))))) {

View File

@@ -61,6 +61,8 @@
#include <BRep_TEdge.hxx>
#include <BRep_GCurve.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <TopExp_Explorer.hxx>
#include <Geom2d_Line.hxx>
static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
const Standard_Real newU1,
@@ -152,7 +154,39 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
{
Standard_Real Up = S->UPeriod();
if (U2 - U1 > Up)
{
//Try to define "exact" U1 according to pcurve of seem edge
TopExp_Explorer anExp(F, TopAbs_EDGE);
for(; anExp.More(); anExp.Next())
{
const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
if(BRep_Tool::IsClosed(anE, F))
{
Standard_Real f, l;
Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anE, F, f, l);
Handle(Standard_Type) aType = aC2d->DynamicType();
if(aType == STANDARD_TYPE(Geom2d_TrimmedCurve))
{
Handle(Geom2d_TrimmedCurve) aC2dT = Handle(Geom2d_TrimmedCurve)::DownCast(aC2d);
aC2d = aC2dT->BasisCurve();
aType = aC2d->DynamicType();
}
if(aType == STANDARD_TYPE(Geom2d_Line))
{
Handle(Geom2d_Line) aLin = Handle(Geom2d_Line)::DownCast(aC2d);
gp_XY anYDir(0., 1.);
gp_XY aD = aLin->Direction().XY();
if(aD.IsEqual(anYDir, Precision::Confusion()) ||
aD.IsEqual(-anYDir, Precision::Confusion()) )
{
U1 = aLin->Location().X();
break;
}
}
}
}
U2 = U1 + Up;
}
}
if (IsVp)
{
@@ -494,7 +528,7 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
TopoDS_Edge ERevers = E;
ERevers.Reverse();
C2dBis = BRep_Tool::CurveOnSurface(ERevers,F,f2dBis,l2dBis);
Handle(Standard_Type) TheTypeC2dBis = C2dBis->DynamicType();
//Handle(Standard_Type) TheTypeC2dBis = C2dBis->DynamicType();
C2dBis = new Geom2d_TrimmedCurve(C2dBis,f2dBis, l2dBis);
Geom2dAdaptor_Curve G2dACBis(C2dBis, f2dBis, l2dBis);
Handle(Geom2dAdaptor_HCurve) G2dAHCBis = new Geom2dAdaptor_HCurve(G2dACBis);
@@ -568,7 +602,9 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
}
else {
Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
mylcu.Append(C2dBis);
//mylcu.Append(C2dBis);
Handle(Geom2d_Curve) aC2dBisBspl = Geom2dConvert::CurveToBSplineCurve(C2dBis);
mylcu.Append(aC2dBisBspl);
return Standard_True;
}
}

View File

@@ -65,6 +65,8 @@ void DsgPrs_DiameterPresentation::Add (const Handle(Prs3d_Presentation)& aPresen
// sideline
gp_Pnt center = aCircle.Location();
gp_Vec vecrap (ptoncirc,center);
if (vecrap.SquareMagnitude() < Precision::Confusion())
return;
Standard_Real dist = center.Distance(AttachmentPoint);
Standard_Real aRadius = aCircle.Radius();

View File

@@ -865,16 +865,31 @@ Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
else { // In other cases => Approx
Standard_Real Tol3d=1.e-4;
Standard_Integer MaxDegree =14, MaxSeg;
GeomAbs_Shape cont;
Standard_Integer MaxDegree = 14, MaxSeg;
GeomAbs_Shape ucont = GeomAbs_C0, vcont = GeomAbs_C0;
GeomAdaptor_Surface AS(Sr);
if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
cont=GeomAbs_C1;
else
cont=GeomAbs_C2;
//
if (Sr->IsCNu(2))
{
ucont=GeomAbs_C2;
}
else if(Sr->IsCNu(1))
{
ucont=GeomAbs_C1;
}
//
if (Sr->IsCNv(2))
{
vcont=GeomAbs_C2;
}
else if(Sr->IsCNv(1))
{
vcont=GeomAbs_C1;
}
//
MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
GeomConvert_ApproxSurface BSpS(Sr,Tol3d,cont,cont,
MaxDegree,MaxDegree,MaxSeg,1);
GeomConvert_ApproxSurface BSpS(Sr, Tol3d, ucont, vcont,
MaxDegree, MaxDegree, MaxSeg, 1);
TheSurface = BSpS.Surface();
}
} // Fin du cas direct

View File

@@ -31,6 +31,7 @@
#include <gp_GTrsf.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax2.hxx>
#include <gp_Sphere.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array2OfPnt.hxx>
@@ -59,6 +60,7 @@
#include <Geom_SphericalSurface.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Approx_SweepApproximation.hxx>
#include <AdvApprox_PrefAndRec.hxx>
@@ -67,6 +69,7 @@
#include <Precision.hxx>
#include <ElCLib.hxx>
#include <ElSLib.hxx>
//=======================================================================
//class : GeomFill_Sweep_Eval
@@ -845,25 +848,33 @@ static Standard_Boolean IsSweepParallelSpine (const Handle(GeomFill_LocationLaw)
Standard_Real f = UFirst , l = ULast;
SError = error;
Centre.BaryCenter(1.0, C.Location(), 1.0);
gp_Ax3 AxisOfSphere(Centre, DN, DS);
S = new (Geom_SphericalSurface)
(AxisOfSphere, (RotRadius + C.Radius())/2 );
gp_Ax3 AxisOfSphere(Centre, DN, DS);
gp_Sphere theSphere( AxisOfSphere, (RotRadius + C.Radius())/2 );
S = new Geom_SphericalSurface(theSphere);
// Pour les spheres on ne peut pas controler le parametre
// V (donc U car myExchUV = Standard_True)
// Il faut donc modifier UFirst, ULast...
if (C.Position().Direction().
IsOpposite(AxisOfSphere.YDirection(), 0.1) ) {
Standard_Real fpar = AC.FirstParameter();
Standard_Real lpar = AC.LastParameter();
Handle(Geom_Curve) theSection = new Geom_TrimmedCurve(Section, fpar, lpar);
theSection->Transform(Tf2);
gp_Pnt FirstPoint = theSection->Value(theSection->FirstParameter());
gp_Pnt LastPoint = theSection->Value(theSection->LastParameter());
Standard_Real UfirstOnSec, VfirstOnSec, UlastOnSec, VlastOnSec;
ElSLib::Parameters(theSphere, FirstPoint, UfirstOnSec, VfirstOnSec);
ElSLib::Parameters(theSphere, LastPoint, UlastOnSec, VlastOnSec);
if (VfirstOnSec < VlastOnSec)
{
f = VfirstOnSec;
l = VlastOnSec;
}
else
{
// L'orientation parametrique est inversee
l = 2*M_PI - UFirst;
f = 2*M_PI - ULast;
f = VlastOnSec;
l = VfirstOnSec;
isUReversed = Standard_True;
}
// On calcul le "glissement" parametrique.
Standard_Real rot;
rot = C.Position().XDirection().AngleWithRef
(AxisOfSphere.XDirection(), AxisOfSphere.YDirection());
f -= rot;
l -= rot;
if ( (f >= -M_PI/2) && (l <= M_PI/2)) {
Ok = Standard_True;

View File

@@ -90,6 +90,10 @@
#include <Precision.hxx>
#include <ShapeAnalysis.hxx>
#include <Standard_Failure.hxx>
#include <Standard_ErrorHandler.hxx>
#include <TColgp_HArray2OfXYZ.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray2OfReal.hxx>
@@ -244,29 +248,90 @@ Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle
Standard_Boolean PeriodU = start->IsUPeriodic();
Standard_Boolean PeriodV = start->IsVPeriodic();
if (PeriodU || PeriodV) {
mysurface = Handle(Geom_BSplineSurface)::DownCast(start->Copy());
mysurface = Handle(Geom_BSplineSurface)::DownCast(start->Copy());
//szv#10:PRO19566:05Oct99
Standard_Boolean workaround = !(mysurface->IsURational() || mysurface->IsVRational());
if (workaround) mysurface->SetWeight(1,1,0.3);
Standard_Real Umin = Udeb, Umax = Ufin, Vmin = Vdeb, Vmax = Vfin;
Standard_Real U0,U1,V0,V1;
Standard_Real uShift = 0, vShift = 0;
mysurface->Bounds(U0,U1,V0,V1);
if ( PeriodU ) mysurface->SetUNotPeriodic();
if ( PeriodV ) mysurface->SetVNotPeriodic();
//szv#10:PRO19566:05Oct99
if (workaround) mysurface->SetWeight(1,1,1.);
// cut segment from periodic surfaces for syncronization of pcurves ranges
// and surface bounds (issue 26138)
if (!PeriodU) {
if (Umin < U0)
Umin = U0;
if (U1 < Umax)
Umax = U1;
}
else {
mysurface = start;
if (Abs(Umin - U0) < Precision::PConfusion())
Umin = U0;
if (Abs(Umax - U1) < Precision::PConfusion())
Umax = U1;
uShift = ShapeAnalysis::AdjustToPeriod(Umin, U0, U1);
Umin += uShift;
Umax += uShift;
}
if (!PeriodV) {
if (Vmin < V0)
Vmin = V0;
if (V1 < Vmax)
Vmax = V1;
}
else {
if (Abs(Vmin - V0) < Precision::PConfusion())
Vmin = V0;
if (Abs(Vmax - V1) < Precision::PConfusion())
Vmax = V1;
vShift = ShapeAnalysis::AdjustToPeriod(Vmin, V0, V1);
Vmin += vShift;
Vmax += vShift;
}
if ( Abs(uShift) > Precision::PConfusion() || Abs(vShift) > Precision::PConfusion()) {
Standard_Boolean isNeedSegment = Standard_True;
isNeedSegment = Abs(Umax-Umin) > Precision::PConfusion() &&
Abs(Vmax-Vmin) > Precision::PConfusion();
Standard_Real uMaxShift = 0, vMaxShift = 0;
uMaxShift = ShapeAnalysis::AdjustToPeriod(Ufin, U0, U1);
vMaxShift = ShapeAnalysis::AdjustToPeriod(Vfin, V0, V1);
isNeedSegment &=
(PeriodU && Abs(uShift - uMaxShift) > Precision::PConfusion()) ||
(PeriodV && Abs(vShift - vMaxShift) > Precision::PConfusion());
if (isNeedSegment) {
try {
OCC_CATCH_SIGNALS
Handle(Geom_BSplineSurface) bspl = Handle(Geom_BSplineSurface)::DownCast ( start->Copy() );
if ( ! bspl.IsNull() ) {
bspl->CheckAndSegment(Umin, Umax, Vmin, Vmax);
if ((U1 - U0) - (Umax - Umin) > Precision::PConfusion())
PeriodU = Standard_False;
if ((V1 - V0) - (Vmax - Vmin) > Precision::PConfusion())
PeriodV = Standard_False;
mysurface = bspl;
}
}
catch ( Standard_Failure ) {
#ifdef DEB
cout << "Warning: GeomToIGES_GeomSurface: can't trim bspline" << endl;
cout << "Warning: Exception in Segment(): " ;
Standard_Failure::Caught()->Print(cout);
#endif
}
}
}
//unperiodize surface to get neccessary for IGES standard number of knots and mults
if ( mysurface->IsUPeriodic() ) {
mysurface->SetUNotPeriodic();
}
if ( mysurface->IsVPeriodic() ) {
mysurface->SetVNotPeriodic();
}
Standard_Integer DegU = mysurface->UDegree();
Standard_Integer DegV = mysurface->VDegree();
Standard_Boolean CloseU = mysurface->IsUClosed();
Standard_Boolean CloseV = mysurface->IsVClosed();
//Standard_Boolean PeriodU = start->IsUPeriodic();
//Standard_Boolean PeriodV = start->IsVPeriodic();
Standard_Boolean RationU = mysurface->IsURational();
Standard_Boolean RationV = mysurface->IsVRational();
Standard_Integer NbUPoles = mysurface->NbUPoles();
@@ -349,18 +414,6 @@ Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle
VIndex = Poles->LowerCol();
}
// mjm le 9/10/97 mise en place d`une protection
Standard_Real U1,U2,V1,V2;
Standard_Real Umin = Udeb;
Standard_Real Umax = Ufin;
Standard_Real Vmin = Vdeb;
Standard_Real Vmax = Vfin;
mysurface->Bounds(U1,U2,V1,V2);
if ( U1 > Umin ) Umin = U1;
if ( V1 > Vmin ) Vmin = V1;
if ( U2 < Umax ) Umax = U2;
if ( V2 < Vmax ) Vmax = V2;
BSpline-> Init (IndexU, IndexV, DegU, DegV, CloseU, CloseV, Polynom, PeriodU,
PeriodV, KnotsU, KnotsV, Weights, Poles, Umin, Umax, Vmin, Vmax);
res = BSpline;

View File

@@ -5,8 +5,8 @@
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and / or modify it
-- under the terms of the GNU Lesser General Public version 2.1 as published
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
@@ -20,7 +20,7 @@ package MAT2d
-- Set of geometrys from Geom2d.
uses
GeomAbs,
MMgt,
gp,
Geom2d,
@@ -34,35 +34,18 @@ uses
is
deferred class SketchExplorer;
---Purpose: SletchExplorer contains an iterator on a set of geometrys
-- from Geom2d. It's use by BisectingLocus.
generic class BisectingLocus;
---Purpose: Constuction of the map of the bisector locus on a
-- set of geometrys from Geom2d.
class Tool2d;
---Purpose: Tool2d contains the geometrys of the map. Tool2d
-- contains the set of the geometric's methode used for
-- the map's computation.
class Mat2d instantiates Mat from MAT (Tool2d);
class Tool2d;
class Mat2d;
class Connexion;
---Purpose: a Connexion links two lines.
class MiniPath;
---Purpose: MiniPath computes one minimum path to link all the
-- lines of a set.
class Circuit;
---Purpose: EquiCircuit gives a Circuit passing by all the lines
-- in a set and all the connexions of the minipath associated.
class CutCurve;
---Purpose: Cuts a curve at the extremas of curvature
-- and at the inflections. Constructs a trimmed
-- Curve for each interval.
class SequenceOfConnexion instantiates Sequence from TCollection
(Connexion from MAT2d);

View File

@@ -5,8 +5,8 @@
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and / or modify it
-- under the terms of the GNU Lesser General Public version 2.1 as published
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
@@ -21,11 +21,12 @@ inherits
TShared from MMgt
---Purpose: Constructs a circuit on a set of lines.
--
-- EquiCircuit gives a Circuit passing by all the lines
-- in a set and all the connexions of the minipath associated.
--
uses
JoinType from GeomAbs,
SequenceOfInteger from TColStd,
Geometry from Geom2d,
SequenceOfGeometry from TColGeom2d,
@@ -40,7 +41,9 @@ uses
is
Create returns mutable Circuit from MAT2d;
Create(aJoinType : JoinType from GeomAbs = GeomAbs_Arc;
IsOpenResult : Boolean from Standard = Standard_False)
returns Circuit from MAT2d;
---Category: Computation
@@ -51,6 +54,11 @@ is
Trigo : Boolean)
is static;
IsSharpCorner(me; Geom1, Geom2 : Geometry from Geom2d;
Direction : Real from Standard)
returns Boolean
is static private;
PassByLast(me ; C1,C2 : Connexion from MAT2d)
returns Boolean
is static private;
@@ -75,7 +83,7 @@ is
DoubleLine(me ;
Line : in out SequenceOfGeometry;
Connexions : in out SequenceOfConnexion from MAT2d;
Father : mutable Connexion from MAT2d;
Father : Connexion from MAT2d;
Side : Real)
is static private;
@@ -128,6 +136,8 @@ fields
connexionMap : DataMapOfIntegerConnexion from MAT2d;
linkRefEqui : DataMapOfBiIntSequenceOfInteger from MAT2d;
linesLength : SequenceOfInteger from TColStd;
myJoinType : JoinType from GeomAbs;
myIsOpenResult : Boolean from Standard;
end Circuit;

View File

@@ -5,8 +5,8 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
@@ -67,16 +67,16 @@ static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
const Handle(Geom2d_Geometry)& Geom2,
Standard_Real& DotProd);
static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
const Handle(Geom2d_Geometry)& Geom2,
const Standard_Real& Direction);
//=============================================================================
//function : Constructor
//purpose :
//=============================================================================
MAT2d_Circuit::MAT2d_Circuit()
MAT2d_Circuit::MAT2d_Circuit(const GeomAbs_JoinType aJoinType,
const Standard_Boolean IsOpenResult)
{
myJoinType = aJoinType;
myIsOpenResult = IsOpenResult;
}
//=============================================================================
@@ -109,7 +109,7 @@ void MAT2d_Circuit::Perform
// Detection Lignes ouvertes.
//----------------------------
for ( i = 1; i <= NbLines; i++) {
Handle_Geom2d_TrimmedCurve Curve;
Handle(Geom2d_TrimmedCurve) Curve;
Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).First());
gp_Pnt2d P1 = Curve->StartPoint();
Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).Last());
@@ -203,6 +203,133 @@ void MAT2d_Circuit::Perform
ConstructCircuit(FigItem,IndRefLine,Road);
}
//=======================================================================
//function : IsSharpCorner
//purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
// une cassure saillante par rapport <Direction>
//=======================================================================
Standard_Boolean MAT2d_Circuit::IsSharpCorner(const Handle(Geom2d_Geometry)& Geom1,
const Handle(Geom2d_Geometry)& Geom2,
const Standard_Real Direction) const
{
Standard_Real DotProd;
Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
Standard_Integer NbTest = 1;
Standard_Real DU = Precision::Confusion();
Handle(Geom2d_TrimmedCurve) C1,C2;
C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
// Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
// Standard_Real TolAng = 1.E-5;
Standard_Real TolAng = 1.E-8;
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
if (myJoinType == GeomAbs_Arc)
{
while (NbTest <= 10) {
if ((ProVec)*Direction < -TolAng)
return Standard_True; // Saillant.
if ((ProVec)*Direction > TolAng)
return Standard_False; // Rentrant.
else {
if (DotProd > 0) {
return Standard_False; // Plat.
}
TolAng = 1.E-8;
Standard_Real U1 = C1->LastParameter() - NbTest*DU;
Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
gp_Dir2d Dir1(C1->DN(U1,1));
gp_Dir2d Dir2(C2->DN(U2,1));
DotProd = Dir1.Dot(Dir2);
ProVec = Dir1^Dir2;
NbTest++;
}
}
// Rebroussement.
// on calculde des paralleles aux deux courbes du cote du domaine
// de calcul
// Si pas dintersection => saillant.
// Sinon => rentrant.
Standard_Real D ;
Standard_Real Tol = Precision::Confusion();
Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
gp_Pnt2d P = C1->Value(C1->LastParameter());
gp_Pnt2d P1 = C1->Value(MilC1);
gp_Pnt2d P2 = C2->Value(MilC2);
D = Min(P1.Distance(P),P2.Distance(P));
D /= 10;
if (Direction > 0.) D = -D;
Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
Adaptor3d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter());
Adaptor3d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2);
Geom2dInt_GInter Intersect;
Intersect.Perform(OC1,OC2,Tol,Tol);
#ifdef DEB
static Standard_Boolean Affich = 0;
if (Affich) {
#ifdef DRAW
Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
for (Standard_Integer ki = 0; ki <= 9; ki++) {
gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
dout << dr1;
dout << dr2;
}
dout.Flush();
#endif
}
#endif
if (Intersect.IsDone() && !Intersect.IsEmpty()) {
return Standard_False;
}
else {
return Standard_True;
}
} //end of if (myJoinType == GeomAbs_Arc)
else if (myJoinType == GeomAbs_Intersection)
{
if (Abs(ProVec) <= TolAng &&
DotProd < 0)
{
while (NbTest <= 10)
{
Standard_Real U1 = C1->LastParameter() - NbTest*DU;
Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
gp_Dir2d Dir1(C1->DN(U1,1));
gp_Dir2d Dir2(C2->DN(U2,1));
DotProd = Dir1.Dot(Dir2);
ProVec = Dir1^Dir2;
if ((ProVec)*Direction < -TolAng)
return Standard_True; // Saillant.
if ((ProVec)*Direction > TolAng)
return Standard_False; // Rentrant.
NbTest++;
}
return Standard_False;
}
else
return Standard_False;
}
return Standard_False;
}
//=======================================================================
//function : SubSequence
//purpose :
@@ -352,12 +479,12 @@ void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const
{
Handle(Geom2d_TrimmedCurve) Curve;
Standard_Real DotProd;
Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
for ( Standard_Integer i = 2; i <= Line.Length() - 2; i++) {
if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 ||
DotProd < 0. ) {
@@ -389,15 +516,18 @@ const
//--------------------------
// Completion de la ligne.
//--------------------------
for ( i = NbItems - 1; i > 1; i--){
Type = Line.Value(i)->DynamicType();
if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
Line.Append(Line.Value(i));
}
else {
Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy());
Curve->Reverse();
Line.Append(Curve);
if (!myIsOpenResult)
{
for ( i = NbItems - 1; i > 1; i--){
Type = Line.Value(i)->DynamicType();
if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
Line.Append(Line.Value(i));
}
else {
Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy());
Curve->Reverse();
Line.Append(Curve);
}
}
}
@@ -485,30 +615,34 @@ const
ICorres++;
}
Corres(ICorres) = IndLine;
for (i = 1; i < 2*NbItems - 2; i++) {
if (Corres(i) == 0) Corres(i) = Corres(2*NbItems - i);
}
#ifdef DEB
if (AffichCircuit) {
for (i = 1; i <= 2*NbItems - 2; i++) {
cout<< "Correspondance "<< i<<" -> "<<Corres(i)<<endl;
if (!myIsOpenResult)
{
for (i = 1; i < 2*NbItems - 2; i++) {
if (Corres(i) == 0)
Corres(i) = Corres(2*NbItems - i);
}
#ifdef DEB
if (AffichCircuit) {
for (i = 1; i <= 2*NbItems - 2; i++) {
cout<< "Correspondance "<< i<<" -> "<<Corres(i)<<endl;
}
}
}
#endif
//----------------------------
// Mise a jour des Connexions.
//----------------------------
for ( i = 1; i <= NbConnexions; i++){
CC = ConnexionFrom.ChangeValue(i);
CC->IndexItemOnFirst(Corres(CC->IndexItemOnFirst()));
}
if (!ConnexionFather.IsNull()) {
ConnexionFather
->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond()));
//----------------------------
// Mise a jour des Connexions.
//----------------------------
for ( i = 1; i <= NbConnexions; i++){
CC = ConnexionFrom.ChangeValue(i);
CC->IndexItemOnFirst(Corres(CC->IndexItemOnFirst()));
}
if (!ConnexionFather.IsNull()) {
ConnexionFather
->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond()));
}
}
}
@@ -531,8 +665,8 @@ void MAT2d_Circuit::InsertCorner (TColGeom2d_SequenceOfGeometry& Line) const
if (AffichCircuit) {
if (Insert) {
Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
gp_Pnt2d P = Curve->StartPoint();
#ifdef DRAW
gp_Pnt2d P = Curve->StartPoint();
Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_vert);
dout << dr;
dout.Flush();
@@ -724,106 +858,6 @@ static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
}
//=======================================================================
//function : IsSharpCorner
//purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
// une cassure saillante par rapport <Direction>
//=======================================================================
static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
const Handle(Geom2d_Geometry)& Geom2,
const Standard_Real& Direction)
{
Standard_Real DotProd;
Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
Standard_Integer NbTest = 1;
Standard_Real DU = Precision::Confusion();
Handle(Geom2d_TrimmedCurve) C1,C2;
C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
// Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
// Standard_Real TolAng = 1.E-5;
Standard_Real TolAng = 1.E-8;
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
while (NbTest <= 10) {
if ((ProVec)*Direction < -TolAng)
return Standard_True; // Saillant.
if ((ProVec)*Direction > TolAng)
return Standard_False; // Rentrant.
else {
if (DotProd > 0) {
return Standard_False; // Plat.
}
TolAng = 1.E-8;
Standard_Real U1 = C1->LastParameter() - NbTest*DU;
Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
gp_Dir2d Dir1(C1->DN(U1,1));
gp_Dir2d Dir2(C2->DN(U2,1));
DotProd = Dir1.Dot(Dir2);
ProVec = Dir1^Dir2;
NbTest++;
}
}
// Rebroussement.
// on calculde des paralleles aux deux courbes du cote du domaine
// de calcul
// Si pas dintersection => saillant.
// Sinon => rentrant.
Standard_Real D ;
Standard_Real Tol = Precision::Confusion();
Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
gp_Pnt2d P = C1->Value(C1->LastParameter());
gp_Pnt2d P1 = C1->Value(MilC1);
gp_Pnt2d P2 = C2->Value(MilC2);
D = Min(P1.Distance(P),P2.Distance(P));
D /= 10;
if (Direction > 0.) D = -D;
Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
Adaptor3d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter());
Adaptor3d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2);
Geom2dInt_GInter Intersect;
Intersect.Perform(OC1,OC2,Tol,Tol);
#ifdef DEB
static Standard_Boolean Affich = 0;
if (Affich) {
Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
for (Standard_Integer ki = 0; ki <= 9; ki++) {
gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
#ifdef DRAW
Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
dout << dr1;
dout << dr2;
}
dout.Flush();
#else
}
#endif
}
#endif
if (Intersect.IsDone() && !Intersect.IsEmpty()) {
return Standard_False;
}
else {
return Standard_True;
}
}

114
src/MAT2d/MAT2d_Mat2d.cdl Normal file
View File

@@ -0,0 +1,114 @@
-- Created on: 1992-09-22
-- Created by: Gilles DEBARBOUILLE
-- Copyright (c) 1992-1999 Matra Datavision
-- Copyright (c) 1999-2014 OPEN CASCADE SAS
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
--
-- Alternatively, this file may be used under the terms of Open CASCADE
-- commercial license or contractual agreement.
class Mat2d from MAT2d
---Purpose: this class contains the generic algoritm of
-- computation of the bisecting locus.
uses
Side from MAT,
Bisector from MAT,
ListOfEdge from MAT,
ListOfBisector from MAT,
DataMapOfIntegerBisector from MAT,
DataMapOfIntegerInteger from TColStd,
Tool2d from MAT2d
is
Create(IsOpenResult : Boolean from Standard = Standard_False)
---Purpose: Empty construtor.
returns Mat2d from MAT2d;
--- Category : Computation.
CreateMat(me : in out ; aTool : in out Tool2d from MAT2d)
---Purpose: Algoritm of computation of the bisecting locus.
is static;
CreateMatOpen(me : in out ; aTool : in out Tool2d from MAT2d)
---Purpose: Algoritm of computation of the bisecting locus for
-- open wire.
is static;
IsDone(me) returns Boolean from Standard
---Purpose: Returns <TRUE> if CreateMat has succeeded.
is static;
LoadBisectorsToRemove(me : in out ;
noofbisectorstoremove : in out Integer;
distance1 : Real;
distance2 : Real;
bisector1 : Bisector from MAT;
bisector2 : Bisector from MAT;
bisector3 : Bisector from MAT;
bisector4 : Bisector from MAT)
is static private;
Intersect( me : in out ;
atool : in out Tool2d from MAT2d;
aside : Integer ;
noofbisectorstoremove: in out Integer ;
bisector1 : Bisector from MAT;
bisector2 : Bisector from MAT)
is static private;
--- Category : Querying.
Init(me : in out)
--- Purpose : Initialize an iterator on the set of the roots
-- of the trees of bisectors.
is static;
More(me) returns Boolean
--- Purpose : Return False if there is no more roots.
is static;
Next(me : in out)
--- Purpose : Move to the next root.
is static;
Bisector(me) returns any Bisector from MAT
--- Purpose : Returns the current root.
is static;
SemiInfinite(me) returns Boolean from Standard
--- Purpose : Returns True if there are semi_infinite bisectors.
-- So there is a tree for each semi_infinte bisector.
is static;
NumberOfBisectors(me) returns Integer from Standard
--- Purpose : Returns the total number of bisectors.
is static;
fields
myIsOpenResult : Boolean;
thenumberofbisectors : Integer;
thenumberofedges : Integer;
semiInfinite : Boolean;
theedgelist : ListOfEdge from MAT;
typeofbisectortoremove: DataMapOfIntegerInteger from TColStd;
bisectoronetoremove : DataMapOfIntegerBisector from MAT;
bisectortwotoremove : DataMapOfIntegerBisector from MAT;
bisectormap : DataMapOfIntegerBisector from MAT;
roots : ListOfBisector from MAT;
isDone : Boolean;
end Mat2d;

1662
src/MAT2d/MAT2d_Mat2d.cxx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,8 @@
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and / or modify it
-- under the terms of the GNU Lesser General Public version 2.1 as published
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
@@ -21,7 +21,7 @@ class Tool2d from MAT2d
uses
JoinType from GeomAbs,
Bisec from Bisector,
Side from MAT,
Bisector from MAT,
@@ -47,6 +47,9 @@ is
--- Purpose :<aSide> defines the side of the computation of the map.
is static;
SetJoinType(me : in out ; aJoinType : JoinType from GeomAbs)
is static;
InitItems(me : in out ;
aCircuit : Circuit from MAT2d )
--- Purpose : InitItems cuts the line in Items.
@@ -72,13 +75,15 @@ is
-- Returns the index of this point in <theGeomPnts>.
returns Integer is static;
TangentBefore(me : in out ; anitem : Integer)
TangentBefore(me : in out ; anitem : Integer;
IsOpenResult : Boolean)
--- Purpose : Creates the Tangent at the end of the Item defined
-- by <anitem>. Returns the index of this vector in
-- <theGeomVecs>
returns Integer is static;
TangentAfter(me : in out ; anitem : Integer)
TangentAfter(me : in out ; anitem : Integer;
IsOpenResult : Boolean)
--- Purpose : Creates the Reversed Tangent at the origin of the Item
-- defined by <anitem>. Returns the index of this vector in
-- <theGeomVecs>
@@ -90,11 +95,11 @@ is
-- <theGeomVecs>
returns Integer is static;
CreateBisector(me : in out ; abisector : mutable Bisector from MAT)
CreateBisector(me : in out ; abisector : Bisector from MAT)
--- Purpose : Creates the geometric bisector defined by <abisector>.
is static;
TrimBisector(me : in out ; abisector : mutable Bisector from MAT)
TrimBisector(me : in out ; abisector : Bisector from MAT)
--- Purpose : Trims the geometric bisector by the <firstparameter>
-- of <abisector>.
-- If the parameter is out of the bisector, Return FALSE.
@@ -102,7 +107,7 @@ is
returns Boolean is static;
TrimBisector(me : in out ;
abisector : mutable Bisector from MAT ;
abisector : Bisector from MAT ;
apoint : Integer)
--- Purpose : Trims the geometric bisector by the point of index
-- <apoint> in <theGeomPnts>.
@@ -111,8 +116,8 @@ is
returns Boolean is static;
IntersectBisector(me : in out ;
bisectorone : mutable Bisector from MAT ;
bisectortwo : mutable Bisector from MAT ;
bisectorone : Bisector from MAT ;
bisectortwo : Bisector from MAT ;
intpnt : in out Integer)
--- Purpose : Computes the point of intersection between the
-- bisectors defined by <bisectorone> and
@@ -220,6 +225,7 @@ is
fields
theDirection : Real;
theJoinType : JoinType from GeomAbs;
theNumberOfBisectors : Integer;
theNumberOfPnts : Integer;
theNumberOfVecs : Integer;

View File

@@ -5,8 +5,8 @@
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
@@ -100,6 +100,7 @@ static Standard_Real MAT2d_TOLCONF = 1.e-7;
MAT2d_Tool2d::MAT2d_Tool2d()
{
theDirection = 1.;
theJoinType = GeomAbs_Arc; //default
theNumberOfBisectors = 0;
theNumberOfVecs = 0;
theNumberOfPnts = 0;
@@ -132,6 +133,15 @@ void MAT2d_Tool2d::Sense(const MAT_Side aside)
else theDirection = -1.;
}
//=============================================================================
//function : SetJoinType
//purpose :
//=============================================================================
void MAT2d_Tool2d::SetJoinType(const GeomAbs_JoinType aJoinType)
{
theJoinType = aJoinType;
}
//=============================================================================
//function : NumberOfItems
//purpose :
@@ -189,13 +199,17 @@ Standard_Integer MAT2d_Tool2d::FirstPoint(const Standard_Integer anitem,
//function : TangentBefore
//purpose :
//=============================================================================
Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem)
Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem,
const Standard_Boolean IsOpenResult)
{
Standard_Integer item;
Handle(Geom2d_Curve) curve;
theNumberOfVecs++;
item = (anitem == theCircuit->NumberOfItems()) ? 1 : (anitem + 1);
if (!IsOpenResult)
item = (anitem == theCircuit->NumberOfItems()) ? 1 : (anitem + 1);
else
item = (anitem == theCircuit->NumberOfItems()) ? (anitem - 1) : (anitem + 1);
if (theCircuit->ConnexionOn(item)){
Standard_Real x1,y1,x2,y2;
theCircuit->Connexion(item)->PointOnFirst().Coord(x1,y1);
@@ -212,7 +226,9 @@ Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem)
}
else {
curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
theGeomVecs.Bind(theNumberOfVecs,curve->DN(curve->FirstParameter(),1));
Standard_Real param = (IsOpenResult && anitem == theCircuit->NumberOfItems())?
curve->LastParameter() : curve->FirstParameter();
theGeomVecs.Bind(theNumberOfVecs,curve->DN(param,1));
}
return theNumberOfVecs;
@@ -222,7 +238,8 @@ Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem)
//function : TangentAfter
//purpose :
//=============================================================================
Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem)
Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem,
const Standard_Boolean IsOpenResult)
{
Standard_Integer item;
Handle(Geom2d_Curve) curve;
@@ -244,9 +261,14 @@ Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem)
thevector = curve->DN(curve->FirstParameter(),1);
}
else {
item = (anitem == 1) ? theCircuit->NumberOfItems() : (anitem - 1);
if (!IsOpenResult)
item = (anitem == 1) ? theCircuit->NumberOfItems() : (anitem - 1);
else
item = (anitem == 1) ? 2 : (anitem - 1);
curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
thevector = curve->DN(curve->LastParameter(),1);
Standard_Real param = (IsOpenResult && anitem == 1)?
curve->FirstParameter() : curve->LastParameter();
thevector = curve->DN(param,1);
}
theGeomVecs.Bind(theNumberOfVecs,thevector.Reversed());
return theNumberOfVecs;
@@ -406,8 +428,7 @@ void MAT2d_Tool2d::TrimBisec ( Bisector_Bisec& B1,
//gp_Vec2d Tan1,Tan2;
gp_Pnt2d Ori; //PEdge;
Standard_Integer IPrec,INext;
IPrec = (IndexEdge == 1) ? theCircuit->NumberOfItems() : (IndexEdge - 1);
Standard_Integer INext;
INext = (IndexEdge == theCircuit->NumberOfItems()) ? 1 : (IndexEdge + 1);
Handle(Standard_Type) EdgeType = theCircuit->Value(IndexEdge)->DynamicType();
@@ -535,7 +556,6 @@ Standard_Boolean MAT2d_Tool2d::Projection (const Standard_Integer IEdge ,
Handle(Standard_Type) Type = Elt->DynamicType();
Handle(Geom2d_TrimmedCurve) Curve;
Standard_Integer INext;
Standard_Real ParameterOnC;
Standard_Real Eps = MAT2d_TOLCONF;//*10.;
if (Type == STANDARD_TYPE(Geom2d_CartesianPoint)) {
@@ -586,7 +606,6 @@ Standard_Boolean MAT2d_Tool2d::Projection (const Standard_Integer IEdge ,
if (Extremas.NbExt() == 0 ) return Standard_False; // Pas de solution!
for (Standard_Integer i = 1; i <= Extremas.NbExt(); i++) {
if (Extremas.SquareDistance(i) < Distance * Distance) {
ParameterOnC = Extremas.Point(i).Parameter();
Distance = sqrt (Extremas.SquareDistance(i));
}
}
@@ -640,6 +659,9 @@ Standard_Boolean MAT2d_Tool2d::IsSameDistance (
Standard_Real EpsDist = MAT2d_TOLCONF*100. ;
Distance = Dist(1);
for (Standard_Integer i = 1; i <= 4; i++){
if (theJoinType == GeomAbs_Intersection &&
Precision::IsInfinite(Dist(i)))
continue;
if (Abs(Dist(i) - Distance) > EpsDist) {
Distance = Precision::Infinite();
return Standard_False;

View File

@@ -0,0 +1,51 @@
// Created on: 2014-03-31
// Created by: Kirill Gavrilov
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <NCollection_AlignedAllocator.hxx>
#include <NCollection_Buffer.hxx>
IMPLEMENT_STANDARD_HANDLE (NCollection_AlignedAllocator, NCollection_BaseAllocator)
IMPLEMENT_STANDARD_RTTIEXT (NCollection_AlignedAllocator, NCollection_BaseAllocator)
IMPLEMENT_STANDARD_HANDLE (NCollection_Buffer, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT (NCollection_Buffer, Standard_Transient)
//=======================================================================
//function : NCollection_AlignedAllocator()
//purpose : Constructor
//=======================================================================
NCollection_AlignedAllocator::NCollection_AlignedAllocator (const size_t theAlignment)
: myAlignment (theAlignment)
{
//
}
//=======================================================================
//function : Allocate
//purpose : allocate a memory
//=======================================================================
void* NCollection_AlignedAllocator::Allocate (const size_t theSize)
{
return Standard::AllocateAligned (theSize, myAlignment);
}
//=======================================================================
//function : Free
//purpose :
//=======================================================================
void NCollection_AlignedAllocator::Free (void* thePtr)
{
Standard::FreeAligned (thePtr);
}

View File

@@ -0,0 +1,56 @@
// Created on: 2014-03-31
// Created by: Kirill Gavrilov
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef NCollection_AlignedAllocator_HeaderFile
#define NCollection_AlignedAllocator_HeaderFile
#include <NCollection_BaseAllocator.hxx>
#include <Standard.hxx>
//! NCollection allocator with managed memory alignment capabilities.
class NCollection_AlignedAllocator : public NCollection_BaseAllocator
{
public:
//! Constructor. The alignment should be specified explicitly:
//! 16 bytes for SSE instructions
//! 32 bytes for AVX instructions
Standard_EXPORT NCollection_AlignedAllocator (const size_t theAlignment);
//! Allocate memory with given size. Returns NULL on failure.
Standard_EXPORT virtual void* Allocate (const size_t theSize);
//! Free a previously allocated memory.
Standard_EXPORT virtual void Free (void* thePtr);
private:
NCollection_AlignedAllocator (const NCollection_AlignedAllocator& );
NCollection_AlignedAllocator& operator= (const NCollection_AlignedAllocator& );
protected:
size_t myAlignment; //!< alignment in bytes
public:
DEFINE_STANDARD_RTTI (NCollection_AlignedAllocator)
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NCollection_AlignedAllocator, NCollection_BaseAllocator)
#endif // NCollection_AlignedAllocator_HeaderFile

View File

@@ -0,0 +1,139 @@
// Created on: 2014-04-01
// Created by: Kirill Gavrilov
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _NCollection_Buffer_HeaderFile
#define _NCollection_Buffer_HeaderFile
#include <NCollection_BaseAllocator.hxx>
#include <Standard_Transient.hxx>
//! Low-level buffer object.
class NCollection_Buffer : public Standard_Transient
{
public:
//! Default constructor.
//! When theData is NULL but theSize is not 0 than buffer of specified size will be allocated.
//! @param theAlloc memory allocator
//! @param theSize buffer size
//! @param theData buffer data allocated by theAlloc
NCollection_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc,
const Standard_Size theSize = 0,
Standard_Byte* theData = NULL)
: myData (NULL),
mySize (0),
myAllocator (theAlloc)
{
if (theData != NULL)
{
myData = theData;
mySize = theSize;
}
else
{
Allocate (theSize);
}
}
//! Destructor.
~NCollection_Buffer()
{
Free();
}
//! @return buffer data
const Standard_Byte* Data() const
{
return myData;
}
//! @return buffer data
Standard_Byte* ChangeData()
{
return myData;
}
//! @return true if buffer is not allocated
bool IsEmpty() const
{
return myData == NULL;
}
//! Return buffer length in bytes.
Standard_Size Size() const
{
return mySize;
}
//! @return buffer allocator
const Handle(NCollection_BaseAllocator)& Allocator() const
{
return myAllocator;
}
//! Assign new buffer allocator with de-allocation of buffer.
void SetAllocator (const Handle(NCollection_BaseAllocator)& theAlloc)
{
Free();
myAllocator = theAlloc;
}
//! Allocate the buffer.
//! @param theSize buffer length in bytes
bool Allocate (const Standard_Size theSize)
{
Free();
mySize = theSize;
if (theSize != 0
|| !myAllocator.IsNull())
{
myData = (Standard_Byte* )myAllocator->Allocate (theSize);
}
if (myData == NULL)
{
mySize = 0;
return false;
}
return true;
}
//! De-allocate buffer.
void Free()
{
if (!myAllocator.IsNull())
{
myAllocator->Free (myData);
}
myData = NULL;
mySize = 0;
}
protected:
Standard_Byte* myData; //!< data pointer
Standard_Size mySize; //!< buffer length in bytes
Handle(NCollection_BaseAllocator) myAllocator; //!< buffer allocator
public:
DEFINE_STANDARD_RTTI(NCollection_Buffer) // Type definition
};
DEFINE_STANDARD_HANDLE(NCollection_Buffer, Standard_Transient)
#endif // _NCollection_Buffer_HeaderFile

View File

@@ -1,17 +1,22 @@
// Created on: 2002-07-30
// Created by: Michael SAZONOV
// Copyright (c) 2002-2014 OPEN CASCADE SAS
// Copyright (c) 2002-2012 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#ifndef NCollection_UBTree_HeaderFile
#define NCollection_UBTree_HeaderFile
@@ -209,7 +214,7 @@ template <class TheObjType, class TheBndType> class NCollection_UBTree
* This method should be used instead of operator delete.
*/
static void delNode (TreeNode * theNode,
Handle(NCollection_BaseAllocator)& theAlloc)
const Handle(NCollection_BaseAllocator)& theAlloc)
{
if (theNode) {
if (theNode -> myChildren) {

View File

@@ -0,0 +1,87 @@
// File: NCollection_WinHeapAllocator.cxx
// Created: 22.07.11
// Author: Kirill GAVRILOV
// Copyright: Open Cascade 2011
#include <NCollection_WinHeapAllocator.hxx>
#include <Standard_OutOfMemory.hxx>
#if(defined(_WIN32) || defined(__WIN32__))
#include <windows.h>
#endif
IMPLEMENT_STANDARD_HANDLE (NCollection_WinHeapAllocator,
NCollection_BaseAllocator)
IMPLEMENT_STANDARD_RTTIEXT(NCollection_WinHeapAllocator,
NCollection_BaseAllocator)
//=======================================================================
//function : NCollection_WinHeapAllocator
//purpose : Main constructor
//=======================================================================
NCollection_WinHeapAllocator::NCollection_WinHeapAllocator
(const size_t theInitSizeBytes)
: NCollection_BaseAllocator(),
#if(defined(_WIN32) || defined(__WIN32__))
myHeapH (HeapCreate (0, theInitSizeBytes, 0)),
#endif
myToZeroMemory (Standard_False)
{
#if(defined(_WIN32) || defined(__WIN32__))
// activate LHF to improve small size allocations
ULONG aHeapInfo = 2;
HeapSetInformation (myHeapH, HeapCompatibilityInformation,
&aHeapInfo, sizeof(aHeapInfo));
#endif
}
//=======================================================================
//function : ~NCollection_WinHeapAllocator
//purpose : Destructor
//=======================================================================
NCollection_WinHeapAllocator::~NCollection_WinHeapAllocator()
{
#if(defined(_WIN32) || defined(__WIN32__))
HeapDestroy (myHeapH);
#endif
}
//=======================================================================
//function : Allocate
//purpose :
//=======================================================================
void* NCollection_WinHeapAllocator::Allocate (const Standard_Size theSize)
{
// the size is rounded up to word size.
const Standard_Size aRoundSize = (theSize + 3) & ~0x3;
#if(defined(_WIN32) || defined(__WIN32__))
void* aResult = HeapAlloc (myHeapH, myToZeroMemory ? HEAP_ZERO_MEMORY : 0,
aRoundSize);
#else
void* aResult = malloc (aRoundSize);
#endif
if (aResult == NULL)
{
char aBuf[128];
sprintf (aBuf, "Failed to allocate %d bytes in local dynamic heap", theSize);
Standard_OutOfMemory::Raise (&aBuf[0]);
}
return aResult;
}
//=======================================================================
//function : Free
//purpose :
//=======================================================================
void NCollection_WinHeapAllocator::Free (void* theAddress)
{
if (theAddress != NULL)
{
#if(defined(_WIN32) || defined(__WIN32__))
HeapFree (myHeapH, 0, theAddress);
#else
free (theAddress);
#endif
}
}

View File

@@ -0,0 +1,55 @@
// File: NCollection_WinHeapAllocator.hxx
// Created: 22.07.11
// Author: Kirill GAVRILOV
// Copyright: Open Cascade 2011
#ifndef NCollection_WinHeapAllocator_HeaderFile
#define NCollection_WinHeapAllocator_HeaderFile
#include <NCollection_BaseAllocator.hxx>
//! This memory allocator creates dedicated heap for allocations.
//! This technics available only on Windows platform
//! (no alternative on Unix systems).
//! It may be used to take control over memory fragmentation
//! because on destruction ALL allocated memory will be released
//! to the system.
//!
//! This allocator can also be created per each working thread
//! hovewer it real multi-threading performance is dubious.
//!
//! Notice that this also means that existing pointers will be broken
//! and you shoould control that allocator is alive along all objects
//! allocated with him.
class NCollection_WinHeapAllocator : public NCollection_BaseAllocator
{
public:
//! Main constructor
Standard_EXPORT NCollection_WinHeapAllocator (const size_t theInitSizeBytes = 0x80000);
Standard_EXPORT virtual ~NCollection_WinHeapAllocator();
Standard_EXPORT virtual void* Allocate (const Standard_Size theSize);
Standard_EXPORT virtual void Free (void* theAddress);
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI(NCollection_WinHeapAllocator)
private:
//! Copy constructor - prohibited
NCollection_WinHeapAllocator (const NCollection_WinHeapAllocator& );
private:
#if(defined(_WIN32) || defined(__WIN32__))
void* myHeapH;
#endif
Standard_Boolean myToZeroMemory;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NCollection_WinHeapAllocator, NCollection_BaseAllocator)
#endif //NCollection_WinHeapAllocator_HeaderFile

View File

@@ -6,24 +6,43 @@ NIS_Drawer.cxx
NIS_Drawer.hxx
NIS_DrawList.cxx
NIS_DrawList.hxx
NIS_IndexLists.cxx
NIS_IndexLists.hxx
NIS_InteractiveContext.cxx
NIS_InteractiveContext.hxx
NIS_InteractiveObject.cxx
NIS_InteractiveObject.hxx
NIS_Line.cxx
NIS_Line.hxx
NIS_LineDrawer.cxx
NIS_LineDrawer.hxx
NIS_ObjectsIterator.cxx
NIS_ObjectsIterator.hxx
NIS_Point.cxx
NIS_Point.hxx
NIS_PointDrawer.cxx
NIS_PointDrawer.hxx
NIS_PolygonSelector.cxx
NIS_PolygonSelector.hxx
NIS_SelectFilter.cxx
NIS_SelectFilter.hxx
NIS_Surface.cxx
NIS_Surface.hxx
NIS_SurfaceDrawer.cxx
NIS_SurfaceDrawer.hxx
NIS_Text.cxx
NIS_Text.hxx
NIS_TextDrawer.cxx
NIS_TextDrawer.hxx
NIS_Tools.cxx
NIS_Tools.hxx
NIS_Triangulated.cxx
NIS_Triangulated.hxx
NIS_TriangulatedDrawer.cxx
NIS_TriangulatedDrawer.hxx
NIS_View.cxx
NIS_View.hxx
NIS_ViewData.hxx
Handle_NIS_InteractiveObject.hxx
Handle_NIS_View.hxx
NIS_CMPLRS.edl

View File

@@ -22,6 +22,7 @@
* Subclass of Incremental Allocator. It is aware of the total
* allocated and released memory. Used in NIS_Interactive context as
* private allocator that manages all memory used by interactive objects.
* @ingroup nis_library
*/
class NIS_Allocator : public NCollection_IncAllocator

View File

@@ -24,6 +24,7 @@
//=======================================================================
NIS_DrawList::NIS_DrawList ()
: myIsCompiled(Standard_False)
{
#ifdef ARRAY_LISTS
myListID = 0;
@@ -47,7 +48,8 @@ NIS_DrawList::NIS_DrawList ()
//=======================================================================
NIS_DrawList::NIS_DrawList (const Handle_NIS_View& theView)
: myView (theView)
: myView (theView),
myIsCompiled(Standard_False)
{
#ifdef ARRAY_LISTS
myListID = 0;
@@ -157,9 +159,12 @@ void NIS_DrawList::BeginPrepare (const Standard_Integer theType)
//purpose :
//=======================================================================
void NIS_DrawList::EndPrepare (const Standard_Integer theType)
void NIS_DrawList::EndPrepare (const Standard_Integer theType,
const Standard_Boolean isCompiled)
{
glEndList ();
if (isCompiled)
glEndList ();
myIsCompiled = isCompiled;
myIsUpdated[theType] = Standard_False;
}
@@ -170,7 +175,8 @@ void NIS_DrawList::EndPrepare (const Standard_Integer theType)
void NIS_DrawList::Call (const Standard_Integer theType)
{
glCallList (GetListID (theType));
if (myIsCompiled)
glCallList (GetListID (theType));
}
//=======================================================================

View File

@@ -27,6 +27,7 @@ class NIS_InteractiveContext;
* in the given drawer are removed.
* When the macro is undefined every draw list is created when needed and it is
* destroyed when there is no objects to show in this draw list.
* @ingroup nis_library
*/
//#define ARRAY_LISTS
@@ -47,7 +48,9 @@ class NIS_DrawList
Standard_EXPORT NIS_DrawList ();
/**
* Constructor
* Constructor.
* @param theView
* View instance where the list is created; for shared lists it is NULL.
*/
Standard_EXPORT NIS_DrawList (const Handle_NIS_View& theView);
@@ -95,8 +98,12 @@ class NIS_DrawList
* by BeginPrepare.
* @param theType
* Integer value coinciding with the enumerated NIS_Drawer::DrawType.
* @param isComp
* Defines if the list should be compiled and then called. Otherwise
* OpenGL list is not created but the commands are executed immediately.
*/
Standard_EXPORT virtual void EndPrepare (const Standard_Integer theType);
Standard_EXPORT virtual void EndPrepare (const Standard_Integer theType,
const Standard_Boolean isComp);
/**
* Call the previously prepared list when the screen is redrawn.
@@ -153,7 +160,7 @@ class NIS_DrawList
NIS_DrawList (const NIS_DrawList& theOther);
// NIS_DrawList& operator = (const NIS_DrawList& theOther);
private:
protected:
// ---------- PRIVATE FIELDS ----------
Handle_NIS_View myView;
@@ -163,6 +170,7 @@ class NIS_DrawList
Standard_Integer myListID[5];
#endif
Standard_Boolean myIsUpdated[5];
Standard_Boolean myIsCompiled;
NCollection_List<Handle_NIS_InteractiveObject> myDynHilighted;
};

View File

@@ -20,10 +20,44 @@
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_NullValue.hxx>
IMPLEMENT_STANDARD_HANDLE (NIS_Drawer, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT (NIS_Drawer, Standard_Transient)
//=======================================================================
//function : NIS_Drawer
//purpose : Constructor
//=======================================================================
NIS_Drawer::NIS_Drawer (const Quantity_Color& theHilight,
const Quantity_Color& theDynHilight)
: myTransparency (0.f),
myIniId (0),
myObjPerDrawer (1024),
myPriority (Priority_Default),
myIsCompiled (Standard_True),
myCtx (0L)
{
myColor[Draw_Hilighted] = theHilight;
myColor[Draw_DynHilighted] = theDynHilight;
}
//=======================================================================
//function : SetCompiled
//purpose :
//=======================================================================
void NIS_Drawer::SetCompiled (const Standard_Boolean isCompiled)
{
if (isCompiled) {
if (myIsCompiled == Standard_False)
SetUpdated(Draw_Normal, Draw_Top, Draw_Transparent, Draw_Hilighted);
}
myIsCompiled = isCompiled;
}
//=======================================================================
//function : NIS_Drawer
//purpose : Destructor
@@ -47,7 +81,14 @@ void NIS_Drawer::Assign (const Handle_NIS_Drawer& theOther)
Standard_TypeMismatch::Raise ("NIS_Drawer::Assign");
myIniId = theOther->myIniId;
myObjPerDrawer = theOther->myObjPerDrawer;
myPriority = theOther->myPriority;
myIsCompiled = theOther->myIsCompiled;
myTransparency = theOther->myTransparency;
myColor[Draw_Normal] = theOther->myColor[Draw_Normal];
myColor[Draw_Top] = theOther->myColor[Draw_Top];
myColor[Draw_Transparent] = theOther->myColor[Draw_Transparent];
myColor[Draw_Hilighted] = theOther->myColor[Draw_Hilighted];
myColor[Draw_DynHilighted] = theOther->myColor[Draw_DynHilighted];
}
//=======================================================================
@@ -62,6 +103,18 @@ Standard_Integer NIS_Drawer::HashCode(const Standard_Integer theN) const
return ((aKey & 0x7fffffff) % theN) + 1;
}
//=======================================================================
//function : areEqual
//purpose : Compare two colors, return True if they seem to be equal
//=======================================================================
Standard_Boolean NIS_Drawer::areEqual (const Quantity_Color& theColor0,
const Quantity_Color& theColor1)
{
static const Standard_Real anEps2 = 1e-7;
return (theColor0.SquareDistance(theColor1) < anEps2);
}
//=======================================================================
//function : IsEqual
//purpose :
@@ -69,17 +122,24 @@ Standard_Integer NIS_Drawer::HashCode(const Standard_Integer theN) const
Standard_Boolean NIS_Drawer::IsEqual (const Handle_NIS_Drawer& theOther) const
{
Standard_Boolean aResult (Standard_False);
if (theOther.IsNull() == Standard_False)
if (DynamicType() == theOther->DynamicType())
if (theOther->myIniId/theOther->myObjPerDrawer == myIniId/myObjPerDrawer)
aResult = Standard_True;
if (theOther.IsNull()
|| DynamicType() != theOther->DynamicType()
|| (theOther->myIniId/theOther->myObjPerDrawer != myIniId/myObjPerDrawer)
|| theOther->myPriority != myPriority
|| theOther->myIsCompiled != myIsCompiled
|| fabs(myTransparency - theOther->myTransparency) > 0.01)
{
return Standard_False;
}
if (aResult)
if (fabs(myTransparency - theOther->myTransparency) > 0.01)
aResult = Standard_False;
return aResult;
for (Standard_Integer i = 0; i < 5; i++)
{
if (!areEqual (theOther->myColor[i], myColor[i]))
{
return Standard_False;
}
}
return Standard_True;
}
//=======================================================================
@@ -147,10 +207,13 @@ void NIS_Drawer::redraw (const DrawType theType,
NIS_DrawList& aDrawList = * anIter.ChangeValue();
const Handle_NIS_View& aView = aDrawList.GetView();
if (aView == theView || aView.IsNull()) {
if (aDrawList.IsUpdated(theType)) {
if (aDrawList.IsUpdated(theType) || myIsCompiled == Standard_False) {
// Get the IDs of objects concerned
TColStd_PackedMapOfInteger mapObj;
mapObj.Intersection (myCtx->myMapObjects[theType], myMapID);
if (theType != NIS_Drawer::Draw_DynHilighted)
{
mapObj.Intersection (myCtx->GetObjectsOfType (theType), myMapID);
}
#ifndef ARRAY_LISTS
// Release the list that is no more in use
if (mapObj.IsEmpty() && theType != Draw_DynHilighted) {
@@ -158,9 +221,10 @@ void NIS_Drawer::redraw (const DrawType theType,
break;
}
#endif
aDrawList.BeginPrepare(theType);
if (myIsCompiled)
aDrawList.BeginPrepare(theType);
prepareList (theType, aDrawList, mapObj);
aDrawList.EndPrepare(theType);
aDrawList.EndPrepare(theType, myIsCompiled);
}
if (aDrawList.GetListID(theType) > 0)
aDrawList.Call(theType);
@@ -282,21 +346,53 @@ void NIS_Drawer::SetDynamicHilighted
//=======================================================================
void NIS_Drawer::removeObject (const NIS_InteractiveObject * theObj,
const Standard_Boolean isUpdateViews)
const Standard_Boolean isUpdateViews)
{
const Standard_Integer anID = theObj->ID();
myMapID.Remove (anID);
// Stop dynamic hilighting if it has been activated
if (theObj->IsDynHilighted())
{
SetDynamicHilighted (Standard_False, theObj);
if (myMapID.IsEmpty()) {
UpdateExListId(NULL);
// Remove the drawer from context.
myCtx->myDrawers.Remove(this);
}
// Set Updated for the draw type.
if (myMapID.IsEmpty())
{
UpdateExListId(NULL);
// Remove the drawer from context.
if (myCtx->myDrawers.Remove(this))
{
--myCtx->myPriorities[myPriority];
}
}
else if (theObj->IsHidden() == Standard_False && isUpdateViews)
{
// Set Updated for the draw type.
SetUpdated (theObj->DrawType());
}
}
//=======================================================================
//function : drawObject
//purpose : Draw a single object
//=======================================================================
Standard_Boolean NIS_Drawer::drawObject
(const Handle_NIS_InteractiveObject& theObj,
const DrawType theType,
const NIS_DrawList& theDrawList)
{
Standard_Boolean aResult(Standard_False);
if (theObj->IsHidden() == Standard_False &&
theObj->GetDrawer().operator->() == this)
{
BeforeDraw(theType, theDrawList);
Draw(theObj, theType, theDrawList);
AfterDraw(theType, theDrawList);
aResult = Standard_True;
}
return aResult;
}
//=======================================================================
@@ -313,7 +409,8 @@ void NIS_Drawer::addObject (const NIS_InteractiveObject * theObj,
// Fill the drawer (if new) with DrawList instances for available Views.
if ( myLists.IsEmpty())
{
if (isShareList)
// only compiled lists may be shared between views
if (isShareList && myIsCompiled)
myLists.Append (createDefaultList(NULL));
else {
NCollection_List<Handle_NIS_View>::Iterator anIter(GetContext()->myViews);
@@ -412,3 +509,52 @@ NIS_DrawList* NIS_Drawer::createDefaultList
{
return new NIS_DrawList(theView);
}
//=======================================================================
//function : SetColor
//purpose : Set the color for hilight or dynamic hilight presentation.
//=======================================================================
void NIS_Drawer::SetColor (const NIS_Drawer::DrawType theDrawType,
const Quantity_Color& theColor)
{
Standard_OutOfRange_Raise_if(theDrawType < Draw_Normal ||
theDrawType > Draw_DynHilighted,
"NISDrawer::SetColor: Irrelevant DrawType");
if (theDrawType == Draw_Normal) {
myColor[Draw_Top] = theColor;
myColor[Draw_Transparent] = theColor;
}
myColor[theDrawType] = theColor;
}
//=======================================================================
//function : GetColor
//purpose : Get Hilighted color of the presentation.
//=======================================================================
Quantity_Color NIS_Drawer::GetColor
(const NIS_Drawer::DrawType theDrawType) const
{
Standard_OutOfRange_Raise_if(theDrawType < Draw_Normal ||
theDrawType > Draw_DynHilighted,
"NISDrawer::GetColor: Irrelevant DrawType");
return myColor[theDrawType];
}
//=======================================================================
//function : SetContext
//purpose : Sets the Interactive Context.
//=======================================================================
void NIS_Drawer::SetContext ( NIS_InteractiveContext *theCtx )
{
Standard_NullValue_Raise_if
(theCtx == 0L, "NIS_InteractiveObject::SetContext: context is NULL");
myCtx = theCtx;
if (myCtx->myDrawers.Add (this))
{
++myCtx->myPriorities[myPriority];
}
}

View File

@@ -22,6 +22,7 @@
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
#include <NIS_DrawList.hxx>
#include <Bnd_B3f.hxx>
#include <Quantity_Color.hxx>
#ifdef WNT
#pragma warning (push)
@@ -102,26 +103,59 @@ template <class A> class NCollection_Vector;
* Drawer instances coincide.
* <p>
* @section nis_drawer_cloning Cloning Drawer instances
* It is possible to clone a Drawer instance with the viryual method Assign().
* It is possible to clone a Drawer instance with the virtual method Assign().
* This method copies all visual properties and other important data from the
* Drawer provided as parameter. Method Clone() also should be very carefully
* implemented for any new Drawer type, to make sure that all necessary data
* fields and structures are properly copied.
* <p>
* @section nis_drawer_compiled Compiled lists
* By default a drawer class maintains a number of draw lists each corresponding
* to a set of interactive objects shown inside a common OpenGl list. This is
* the optimal way to achieve the performance but some OpenGL features may be
* incompatible with it. For instance, if you need to provide a pixel position
* or width to GL command (like glDrawPixels) then GL lists will be irelevant -
* normally the lists are not recompiled at any change of viewport geometry.
* <br>
* To overcome this limitation you can define a drawer with IsCompiled property
* set to False, this will guarantee that every refresh will follow the whole
* code of Draw() method including the values that are variable or cannot be
* stored in GL lists.
* @ingroup nis_library
*/
class NIS_Drawer : public Standard_Transient
{
public:
#if defined(WNT) && (_MSC_VER >= 1400)
enum DrawType : unsigned int {
//! Drawing scenarious
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
enum DrawType : unsigned int
#else
enum DrawType {
enum DrawType
#endif
Draw_Normal = 0,
Draw_Top = 1,
Draw_Transparent = 2,
Draw_Hilighted = 3,
Draw_DynHilighted = 4
{
Draw_Normal = 0, //!< normal object
Draw_Top = 1, //!< normal object witj topmost flag
Draw_Transparent = 2, //!< transparent object, drawn after opaque objects
Draw_Hilighted = 3, //!< hilighted (selected) object
Draw_DynHilighted = 4, //!< dynamic hilighted (mouse picking without click)
Draw_TypeNb
};
//! Drawing priority (within drawing scenario)
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
enum PriorityLevel : unsigned int
#else
enum PriorityLevel
#endif
{
Priority_Bottommost = 0, //!< objects to be drawn before others
Priority_Bottom = 1, //!< objects to be drawn before others
Priority_Default = 2, //!< default priority
Priority_Top = 3, //!< objects to be drawn after others
Priority_Topmost = 4, //!< objects to be drawn after others
Priority_LevelsNb
};
public:
@@ -131,12 +165,18 @@ class NIS_Drawer : public Standard_Transient
/**
* Empty constructor.
*/
inline NIS_Drawer ()
: myTransparency (0.f),
myIniId (0),
myObjPerDrawer (1024),
myCtx (0L)
{}
Standard_EXPORT NIS_Drawer
(const Quantity_Color &theHilight = Quantity_NOC_GRAY65,
const Quantity_Color &theDynHilight = Quantity_NOC_CYAN1);
/**
* Set or reset the status 'Compiled'. By default it is "True" meaning that
* every draw list would be compiled once and then called multiple times
* when needed. The value "False" means that all GL commands will be executed
* as they are defined in methods BeforeDraw, Draw and AfterDraw without
* building an OpenGL list.
*/
Standard_EXPORT void SetCompiled (const Standard_Boolean isCompiled);
/**
* Destructor.
@@ -149,6 +189,11 @@ class NIS_Drawer : public Standard_Transient
inline NIS_InteractiveContext * GetContext () const
{ return myCtx; }
/**
* Sets the Interactive Context.
*/
Standard_EXPORT void SetContext ( NIS_InteractiveContext *theCtx );
/**
* Copy the relevant information from another instance of Drawer.
* raises exception if theOther has incompatible type (test IsKind).
@@ -166,19 +211,19 @@ class NIS_Drawer : public Standard_Transient
/**
* Mark all draw lists for update
*/
Standard_EXPORT void SetUpdated (const DrawType theType) const;
Standard_EXPORT virtual void SetUpdated (const DrawType theType) const;
Standard_EXPORT void SetUpdated (const DrawType theType1,
const DrawType theType2) const;
Standard_EXPORT virtual void SetUpdated (const DrawType theType1,
const DrawType theType2) const;
Standard_EXPORT void SetUpdated (const DrawType theType1,
const DrawType theType2,
const DrawType theType3) const;
Standard_EXPORT virtual void SetUpdated (const DrawType theType1,
const DrawType theType2,
const DrawType theType3) const;
Standard_EXPORT void SetUpdated (const DrawType theType1,
const DrawType theType2,
const DrawType theType3,
const DrawType theType4) const;
Standard_EXPORT virtual void SetUpdated (const DrawType theType1,
const DrawType theType2,
const DrawType theType3,
const DrawType theType4) const;
/**
* Switch on/off the dynamic hilight of the given object in the
@@ -191,7 +236,7 @@ class NIS_Drawer : public Standard_Transient
* View where the status of object must be changed. If NULL, the object
* is hilighted/unhilighted in all views.
*/
Standard_EXPORT void SetDynamicHilighted
Standard_EXPORT virtual void SetDynamicHilighted
(const Standard_Boolean isHilighted,
const Handle_NIS_InteractiveObject& theObj,
const Handle_NIS_View& theView = 0L);
@@ -200,7 +245,7 @@ class NIS_Drawer : public Standard_Transient
* Hash value, for Map interface.
*/
Standard_EXPORT virtual Standard_Integer
HashCode(const Standard_Integer theN) const;
HashCode (const Standard_Integer theN) const;
/**
* Matching two instances, for Map interface.
@@ -208,6 +253,30 @@ class NIS_Drawer : public Standard_Transient
Standard_EXPORT virtual Standard_Boolean
IsEqual (const Handle_NIS_Drawer& theOth) const;
/**
* Set the color for presentation.
* @param theDrawType
* Draw type for which the color is defined
* @param theColor
* New color to use for the presentation.
*/
Standard_EXPORT virtual void SetColor (const DrawType theDrawType,
const Quantity_Color& theColor);
/**
* Get color of the presentation in the given DrawType.
* @param theDrawType
* The draw type, for which the color is retrieved.
*/
Standard_EXPORT virtual Quantity_Color
GetColor (const DrawType theDrawType) const;
/**
* Get the transparency value.
*/
inline Standard_ShortReal Transparency () const
{ return myTransparency; }
/**
* Obtain the iterator of IDs of associated objects.
*/
@@ -215,19 +284,47 @@ class NIS_Drawer : public Standard_Transient
ObjectIterator () const
{ return TColStd_MapIteratorOfPackedMapOfInteger (myMapID); }
/**
* Obtain map of IDs of associated objects.
*/
inline const TColStd_PackedMapOfInteger& ObjectsMap() const
{ return myMapID; }
/**
* Query associated draw lists.
*/
inline NCollection_List<NIS_DrawList *>
GetLists() const
GetLists () const
{ return myLists; }
/**
* @return drawer priority within drawing scenario
*/
inline PriorityLevel Priority() const
{ return (PriorityLevel)myPriority; }
/**
* Setup drawer priority within drawing scenario
*/
inline void SetPriority (const PriorityLevel thePriority)
{ myPriority = thePriority; }
/**
* Draw a single object.
* @returns
* True if the object was drawn, False if refused.
*/
Standard_EXPORT virtual Standard_Boolean
drawObject (const Handle_NIS_InteractiveObject&,
const DrawType theType,
const NIS_DrawList& theDrawList);
protected:
/**
* Called to add draw list IDs to ex-list Ids of view. These draw lists are
* eventually released in the callback function, before anything is displayed
*/
Standard_EXPORT void UpdateExListId (const Handle_NIS_View& theView) const;
Standard_EXPORT void UpdateExListId (const Handle_NIS_View& theView) const;
// ---------- PROTECTED METHODS ----------
@@ -265,6 +362,10 @@ protected:
Standard_EXPORT virtual NIS_DrawList*
createDefaultList (const Handle_NIS_View&) const;
Standard_EXPORT static Standard_Boolean
areEqual (const Quantity_Color& theColor0,
const Quantity_Color& theColor1);
protected:
//! Get the number of interactive objects in this drawer
inline Standard_Integer NObjects() const
@@ -291,7 +392,11 @@ protected:
//! Maximal range of IDs of objects in one drawer. Limits the size of
//! draw lists. Can be initialized only in constructor (default 1024). It is
//! strictly prohibited to change this value outside the constructor.
Standard_Integer myObjPerDrawer;
Standard_Integer myObjPerDrawer : 24;
Standard_Integer myPriority : 3;
Standard_Boolean myIsCompiled : 1;
//! Colors for different draw modes: Normal, Top, Transparent, Hilight, DynHi
Quantity_Color myColor[5];
private:
// ---------- PRIVATE FIELDS ----------

289
src/NIS/NIS_IndexLists.cxx Normal file
View File

@@ -0,0 +1,289 @@
// File: NIS_IndexLists.cxx
// Created: 19.07.2011 13:42
// Author:
// Copyright: Open Cascade 2011
#include <NIS_IndexLists.hxx>
#include <NCollection_BaseAllocator.hxx>
#include <Standard_OutOfRange.hxx>
/**
* Compute the size in bytes of an index array.
*/
static inline Standard_Size NBytesInd (const Standard_Size nInd,
const unsigned int theIndType)
{
static const Standard_Size nBytes[] = { 1, 2, 4 };
return nInd * nBytes[theIndType];
}
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
NIS_IndexLists::NIS_IndexLists()
: mypIndexes (0L),
myNbArrays (0u),
myIndexType (2u)
{
}
//=======================================================================
//function : Clear()
//purpose :
//=======================================================================
void NIS_IndexLists::Clear (NCollection_BaseAllocator * theAlloc)
{
if (theAlloc && theAlloc != UndefinedHandleAddress)
{
if (myNbArrays) {
for (unsigned int i = 0; i < myNbArrays; i++)
theAlloc->Free(mypIndexes[i]);
theAlloc->Free(mypIndexes);
myNbArrays = 0u;
mypIndexes = 0L;
}
}
}
//=======================================================================
//function : Clone()
//purpose :
//=======================================================================
void NIS_IndexLists::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
NIS_IndexLists& theDest) const
{
theDest.myNbArrays = myNbArrays;
theDest.myIndexType = myIndexType;
if (myNbArrays) {
const Standard_Size nBytes = sizeof(Standard_Integer *) * myNbArrays;
theDest.mypIndexes = static_cast<Standard_Integer **>
(theAlloc->Allocate(nBytes));
for (unsigned int i = 0; i < myNbArrays; i++) {
const Standard_Size nIdx = NArrayIndexes(i);
const Standard_Size nBytes = NBytesInd(nIdx, myIndexType)+4;
theDest.mypIndexes[i] = static_cast <Standard_Integer *>
(theAlloc->Allocate (nBytes));
memcpy(theDest.mypIndexes[i], mypIndexes[i], nBytes);
}
}
}
//=======================================================================
//function : InitArray
//purpose :
//=======================================================================
void NIS_IndexLists::InitArray (const unsigned int theIndexType,
const Standard_Integer theNLists,
NCollection_BaseAllocator * theAlloc)
{
if (theNLists > 0)
{
Clear(theAlloc);
myIndexType = theIndexType;
myNbArrays = static_cast<unsigned int>(theNLists);
mypIndexes = static_cast<Standard_Integer **>
(theAlloc->Allocate(sizeof(Standard_Integer *) * theNLists));
}
}
//=======================================================================
//function : SetRealNumbersOfArrays
//purpose :
//=======================================================================
void NIS_IndexLists::SetRealNumbersOfArrays (const Standard_Integer theNLists)
{
if (theNLists < 0)
return;
if (theNLists > static_cast<Standard_Integer>(myNbArrays))
Standard_OutOfRange::Raise ("NIS_IndexLists::SetRealNumbersOfArrays");
myNbArrays = static_cast<unsigned int>(theNLists);
}
//=======================================================================
//function : SetArrayIndex
//purpose :
//=======================================================================
void NIS_IndexLists::SetArrayIndex (const Standard_Size theIndArray,
const Standard_Size theIndInArray,
const Standard_Integer theIndex)
{
Standard_OutOfRange_Raise_if (theIndArray >= myNbArrays,
"NIS_IndexLists::SetArrayIndex");
Standard_Integer * aArray = mypIndexes[theIndArray];
switch (myIndexType) {
case 0: // 8bit
{
Standard_OutOfRange_Raise_if (theIndInArray >= aNIdx,
"NIS_IndexLists::SetArrayIndex");
unsigned char * pInd =
reinterpret_cast<unsigned char *>(aArray) + (theIndInArray + 4);
pInd[0] = static_cast<unsigned char>(theIndex);
}
break;
case 1: // 16bit
{
Standard_OutOfRange_Raise_if (theIndInArray >= aNIdx,
"NIS_IndexLists::SetArrayIndex");
unsigned short * pInd =
reinterpret_cast<unsigned short *>(aArray) + (theIndInArray + 2);
pInd[0] = static_cast<unsigned short>(theIndex);
}
break;
default: // 32bit
Standard_OutOfRange_Raise_if (static_cast<int>(theIndInArray) >= aArray[0],
"NIS_IndexLists::SetArrayIndex");
aArray[theIndInArray + 1] = theIndex;
}
}
//=======================================================================
//function : SetArray
//purpose :
//=======================================================================
void NIS_IndexLists::SetArray (const Standard_Size theIndArray,
const Standard_Integer theNbIndexes,
NCollection_BaseAllocator * theAlloc)
{
Standard_OutOfRange_Raise_if (theIndArray >= myNbArrays,
"NIS_IndexLists::SetArray");
switch (myIndexType) {
case 0: // 8bit
{
unsigned char * anArray = static_cast <unsigned char *>
(theAlloc->Allocate (sizeof(unsigned char) * (theNbIndexes+4)));
mypIndexes[theIndArray] = reinterpret_cast<Standard_Integer *> (anArray);
*(reinterpret_cast<unsigned int*>(anArray)) = theNbIndexes;
}
break;
case 1: // 16bit
{
unsigned short * anArray = static_cast <unsigned short *>
(theAlloc->Allocate (sizeof(unsigned short) * (theNbIndexes+2)));
mypIndexes[theIndArray] = reinterpret_cast<Standard_Integer *> (anArray);
*(reinterpret_cast<unsigned int*>(anArray)) = theNbIndexes;
}
break;
default: // 32bit
{
Standard_Integer * anArray = static_cast <Standard_Integer *>
(theAlloc->Allocate (sizeof(Standard_Integer) * (theNbIndexes+1)));
mypIndexes[theIndArray] = anArray;
anArray[0] = theNbIndexes;
}
}
}
//=======================================================================
//function : SetArray
//purpose :
//=======================================================================
void NIS_IndexLists::SetArray (const Standard_Size theIndArray,
const Standard_Integer theNbIndexes,
const int* theIdxList,
NCollection_BaseAllocator * theAlloc,
const Standard_Integer theStartIdx)
{
if (theIdxList)
{
SetArray (theIndArray, theNbIndexes, theAlloc);
if (mypIndexes)
{
for (Standard_Integer i = 0; i < theNbIndexes; i++)
{
Standard_Integer aN = theIdxList[i] + theStartIdx;
SetArrayIndex (theIndArray, i, aN);
}
}
}
}
//=======================================================================
//function : ArrayIndex
//purpose :
//=======================================================================
Standard_Integer NIS_IndexLists::ArrayIndex
(const Standard_Size theIndArray,
const Standard_Integer theIndInArray) const
{
Standard_Integer aResult(-1);
Standard_OutOfRange_Raise_if (theIndArray >= myNbArrays,
"NIS_IndexLists::ArrayIndex");
const Standard_Integer * aArray = mypIndexes[theIndArray];
switch (myIndexType) {
case 0: // 8bit
{
const unsigned char * pInd =
reinterpret_cast<const unsigned char *>(aArray);
Standard_OutOfRange_Raise_if (theIndInArray >= pInd[0],
"NIS_IndexLists::ArrayIndex");
aResult = static_cast<Standard_Integer>(pInd[theIndInArray + 4]);
}
break;
case 1: // 16bit
{
const unsigned short * pInd =
reinterpret_cast<const unsigned short *>(aArray);
Standard_OutOfRange_Raise_if (theIndInArray >= pInd[0],
"NIS_IndexLists::ArrayIndex");
aResult = static_cast<Standard_Integer>(pInd[theIndInArray + 2]);
}
break;
default: // 32bit
{
Standard_OutOfRange_Raise_if (theIndInArray >= aArray[0],
"NIS_IndexLists::ArrayIndex");
aResult = aArray[theIndInArray + 1];
}
}
return aResult;
}
//=======================================================================
//function : NArraysIndexes
//purpose :
//=======================================================================
Standard_Size NIS_IndexLists::NArrayIndexes
(const Standard_Integer theIndArray) const
{
Standard_Size aResult(0);
Standard_OutOfRange_Raise_if ((theIndArray >=
static_cast<Standard_Integer>(myNbArrays)),
"NIS_IndexLists::NArraysIndexes");
const Standard_Integer * aArray = mypIndexes[theIndArray];
aResult = * (reinterpret_cast<const unsigned int *>(aArray));
return aResult;
}
//=======================================================================
//function : ArraysIndexes
//purpose :
//=======================================================================
void * NIS_IndexLists::ArrayIndexes(const Standard_Size theIndArray)const
{
Standard_OutOfRange_Raise_if (theIndArray >= myNbArrays,
"NIS_IndexLists::ArraysIndexes");
void * anArray;
if (myIndexType == 0)
anArray = reinterpret_cast<unsigned char *>(mypIndexes[theIndArray])+4;
else if (myIndexType == 1)
anArray = reinterpret_cast<unsigned short *>(mypIndexes[theIndArray])+2;
else
anArray = mypIndexes[theIndArray]+1;
return anArray;
}

160
src/NIS/NIS_IndexLists.hxx Normal file
View File

@@ -0,0 +1,160 @@
// File: NIS_IndexLists.hxx
// Created: 19.07.2011 15:29
// Author:
// Copyright: Open Cascade 2011
#ifndef NIS_IndexLists_HeaderFile
#define NIS_IndexLists_HeaderFile
#include <Standard_TypeDef.hxx>
class NCollection_BaseAllocator;
class Handle_NCollection_BaseAllocator;
class NIS_IndexLists
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
*/
Standard_EXPORT NIS_IndexLists ();
/**
* Reset all data memebers and free all allocated memory.
* Called from the destructor of the container class, also can be used
* to re-initialize the data set.
* The allocator parameter should be the same as previously passed to
* methods InitArray() and SetArray().
*/
Standard_EXPORT void Clear (NCollection_BaseAllocator* theAlloc);
/**
* Create a copy of object.
* @param theAl
* Allocator where the Dest should store its private data.
* @param theDest
* <tt>[in-out]</tt> The target object where the data are copied. If
* passed NULL then the target should be created.
*/
Standard_EXPORT void Clone
(const Handle_NCollection_BaseAllocator& theAl,
NIS_IndexLists& theDest) const;
/**
* Initialize the array of indexes
* @param theIndexType
* 0:8bit, 1:16bit, 2:32bit
* @param theNLists
* Number of separate array of indexes. If set to 0, array are cancelled
* @param theAlloc
* Allocator that is called for array memory.
*/
Standard_EXPORT void InitArray
(const unsigned int theIndexType,
const Standard_Integer theNLists,
NCollection_BaseAllocator * theAlloc);
/**
* Set the actual number of used arrays. The length can not exceed value specified in InitArray
* @param theNLists
* Number of separate array of indexes. If set to 0, array are cancelled
*/
Standard_EXPORT void SetRealNumbersOfArrays
(const Standard_Integer theNLists);
/**
* Store the element index in array
* @param theIndArray
* Index of the Array, should be less than the number of arrays that is
* defined in InitArray() and can be returned by NArrays().
* @param theIndInArray
* Index of the element in the Array. Should be less than the parameter theSz
* in the corresponding previous SetArray() call.
* @param theIndex
* Index of the element in the given position of the Array.
*/
Standard_EXPORT void SetArrayIndex
(const Standard_Size theIndArray,
const Standard_Size theIndInArray,
const Standard_Integer theIndex);
/**
* Allocate a single array. The array can be filled by indices using
* the method SetArrayIndex().
* @param theIndArray
* Index of the array, should be [0...myNbArrays-1]
* @param theSz
* Number of elements in the array.
* @param theAlloc
* Allocator, should be the same as passed to InitArray() before.
*/
Standard_EXPORT void SetArray
(const Standard_Size theIndArray,
const Standard_Integer theSz,
NCollection_BaseAllocator * theAlloc);
/**
* Store the array elements indexes
* @param theIndArray
* Index of the Array, should be less than the number of arrays that is
* defined in InitArray() and can be returned by NArrays().
* @param theNbIndexes
* size of array
* @param theIdxList
* Array of elements. The size must be equal theNbIndexes
* @param theAlloc
* Allocator, should be the same as passed to InitArray() before.
* @param theStartIdx
* Index that must be added to the element in the array to change
* the indexation, 0 by default.
*/
Standard_EXPORT void SetArray
(const Standard_Size theIndArray,
const Standard_Integer theNbIndexes,
const int* theIdxList,
NCollection_BaseAllocator * theAlloc,
const Standard_Integer theStartIdx=0);
/**
* Get the element with index 'theIndInArray' from the array
* number 'theIndArray'.
*/
Standard_EXPORT Standard_Integer ArrayIndex
(const Standard_Size theIndArray,
const Standard_Integer theIndInArr) const;
/**
* Get the number of elements for the array number 'theIndArray'.
*/
Standard_EXPORT Standard_Size NArrayIndexes
(const Standard_Integer theIndArray) const;
/**
* Get the array of elements for the array number 'theIndArray'.
*/
Standard_EXPORT void* ArrayIndexes (const Standard_Size theIndArray) const;
/**
* Query the number of arrays.
*/
inline Standard_Integer NArrays () const
{ return static_cast<Standard_Integer>(myNbArrays); }
protected:
// ---------- PROTECTED METHODS ----------
private:
// ---------- PRIVATE (PROHIBITED) METHODS ----------
private:
// ---------- PRIVATE FIELDS ----------
Standard_Integer** mypIndexes; ///< Array of indexes
unsigned int myNbArrays : 24; ///< Number of arrays
unsigned int myIndexType : 2; ///< 0:8bit, 1:16bit, 2:32bit
};
#endif

View File

@@ -24,6 +24,15 @@ IMPLEMENT_STANDARD_HANDLE (NIS_InteractiveContext, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT (NIS_InteractiveContext, Standard_Transient)
static void markAllDrawersUpdated (const NCollection_Map<Handle_NIS_Drawer>&);
static Standard_Boolean CanBeAllocated(const Standard_Size theNeedTotal,
const Standard_Size theBlockSize);
#ifdef WNT
#include <windows.h>
static const Standard_Integer aSizeAlloc = 0x80000; // 512k
#else
static const Standard_Integer aSizeAlloc = 0x20000; // 128k
#endif
//=======================================================================
//function : NIS_InteractiveContext()
@@ -31,7 +40,7 @@ static void markAllDrawersUpdated (const NCollection_Map<Handle_NIS_Drawer>&);
//=======================================================================
NIS_InteractiveContext::NIS_InteractiveContext ()
: myAllocator (new NIS_Allocator(1024*100)),
: myAllocator (new NIS_Allocator(aSizeAlloc)),
myLastObjectId (0),
myObjects (1000),
// myDrawers (101, myAllocator),
@@ -40,6 +49,10 @@ NIS_InteractiveContext::NIS_InteractiveContext ()
{
// ID == 0 is invalid so we reserve this item from subsequent allocation.
myObjects.SetValue(myLastObjectId, NULL);
for (Standard_Integer aPriority = 0; aPriority < NIS_Drawer::Priority_LevelsNb; ++aPriority)
{
myPriorities[aPriority] = 0;
}
}
//=======================================================================
@@ -51,15 +64,11 @@ NIS_InteractiveContext::~NIS_InteractiveContext ()
{
// Unregister this context in all referred views
NCollection_List<Handle_NIS_View>::Iterator anIterV (myViews);
for (; anIterV.More(); anIterV.Next())
if (anIterV.Value().IsNull() == Standard_False)
anIterV.Value()->RemoveContext(this);
// // Unregister this context in all referred drawers
// NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (myDrawers);
// for (; anIterD.More(); anIterD.Next())
// if (anIterD.Value().IsNull() == Standard_False)
// anIterD.Value()->myCtx = 0L;
while (anIterV.More())
if (anIterV.Value().IsNull())
anIterV.Next();
else
detachView(anIterV);
}
@@ -84,6 +93,10 @@ void NIS_InteractiveContext::AttachView (const Handle_NIS_View& theView)
if (aDrawer.IsNull() == Standard_False)
aDrawer->myLists.Append(aDrawer->createDefaultList(theView));
}
if (myIsShareDrawList && NbObjects() > 0)
{
markAllDrawersUpdated( myDrawers );
}
}
}
}
@@ -99,26 +112,48 @@ void NIS_InteractiveContext::DetachView (const Handle_NIS_View& theView)
NCollection_List<Handle_NIS_View>::Iterator anIter (myViews);
for (; anIter.More(); anIter.Next())
if (anIter.Value() == theView) {
myViews.Remove(anIter);
theView->RemoveContext(this);
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (myDrawers);
for (; anIterD.More(); anIterD.Next()) {
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
if (aDrawer.IsNull() == Standard_False) {
NCollection_List<NIS_DrawList*>::Iterator anIterL(aDrawer->myLists);
for (; anIterL.More(); anIterL.Next())
if (anIterL.Value()->GetView() == theView) {
delete anIterL.Value();
aDrawer->myLists.Remove (anIterL);
break;
}
}
}
detachView(anIter);
break;
}
}
}
//=======================================================================
//function : detachView
//purpose :
//=======================================================================
void NIS_InteractiveContext::detachView
(NCollection_List<Handle_NIS_View>::Iterator& theIter)
{
if (theIter.More()) {
const Handle(NIS_View)& aView = theIter.Value();
// If draw lists are shared in this Context then they should be
// destroyed when we detach from the last view.
Standard_Boolean isForcedDestroy(Standard_False);
aView->RemoveContext(this); // must be called before myViews.Remove()
myViews.Remove(theIter);
if (myIsShareDrawList && myViews.IsEmpty())
isForcedDestroy = Standard_True;
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (myDrawers);
for (; anIterD.More(); anIterD.Next()) {
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
if (aDrawer.IsNull() == Standard_False) {
NCollection_List<NIS_DrawList*>::Iterator anIterL(aDrawer->myLists);
for (; anIterL.More(); anIterL.Next()) {
NIS_DrawList* pList = anIterL.Value();
if (isForcedDestroy || pList->GetView() == aView) {
delete pList;
aDrawer->myLists.Remove (anIterL);
break;
}
}
}
}
}
}
//=======================================================================
//function : GetObject
//purpose :
@@ -137,16 +172,28 @@ const Handle_NIS_InteractiveObject& NIS_InteractiveContext::GetObject
//=======================================================================
//function : redraw
//purpose :
//purpose :
//=======================================================================
void NIS_InteractiveContext::redraw (const Handle(NIS_View)& theView,
const NIS_Drawer::DrawType theType)
void NIS_InteractiveContext::redraw (const Handle(NIS_View)& theView,
const NIS_Drawer::DrawType theType,
const NIS_Drawer::PriorityLevel thePriority)
{
if (thePriority >= NIS_Drawer::Priority_LevelsNb
|| myPriorities[thePriority] < 1)
{
return;
}
NCollection_Map <Handle_NIS_Drawer>::Iterator anIter (myDrawers);
for (; anIter.More(); anIter.Next())
if (anIter.Value().IsNull() == Standard_False)
{
if (anIter.Value().IsNull() == Standard_False
&& anIter.Value()->Priority() == thePriority)
{
anIter.Value()->redraw (theType, theView);
}
}
}
//=======================================================================
@@ -379,6 +426,10 @@ void NIS_InteractiveContext::RemoveAll ()
}
// Remove Drawers
myDrawers.Clear();
for (Standard_Integer anIter = 0; anIter < NIS_Drawer::Priority_LevelsNb; ++anIter)
{
myPriorities[anIter] = 0;
}
// Release memory
myAllocator->Reset();
@@ -474,7 +525,7 @@ Standard_Boolean NIS_InteractiveContext::SetSelected
Standard_Boolean NIS_InteractiveContext::ProcessSelection
(const Handle_NIS_InteractiveObject& theObj,
const Standard_Boolean isMultiple)
const Standard_Boolean isModifierUsed)
{
Standard_Boolean aResult (Standard_False);
Standard_Integer anID (0);
@@ -492,16 +543,18 @@ Standard_Boolean NIS_InteractiveContext::ProcessSelection
switch (mySelectionMode) {
case Mode_Normal:
case Mode_Additive:
if (isMultiple == Standard_False) {
ClearSelected();
if (isModifierUsed == Standard_False) {
if (mySelectionMode == Mode_Normal)
ClearSelected();
wasSelected = myMapObjects[NIS_Drawer::Draw_Hilighted].Contains (anID);
aResult = Standard_True;
} else if (wasSelected && mySelectionMode == Mode_Normal) {
} else if (wasSelected) {
myMapObjects[NIS_Drawer::Draw_Hilighted].Remove( anID );
deselectObj (theObj, anID);
aResult = Standard_True;
break;
}
if (wasSelected == Standard_False && IsSelectable(anID) == Standard_True) {
if (wasSelected == Standard_False && IsSelectable(anID) == Standard_True && anID > 0) {
myMapObjects[NIS_Drawer::Draw_Hilighted].Add( anID );
selectObj (theObj, anID);
aResult = Standard_True;
@@ -526,7 +579,7 @@ Standard_Boolean NIS_InteractiveContext::ProcessSelection
void NIS_InteractiveContext::ProcessSelection
(const TColStd_PackedMapOfInteger& mapSel,
const Standard_Boolean isMultiple)
const Standard_Boolean isModifierUsed)
{
//subtract non-selectable objects
TColStd_PackedMapOfInteger aMap;
@@ -535,14 +588,27 @@ void NIS_InteractiveContext::ProcessSelection
TColStd_MapIteratorOfPackedMapOfInteger anIter;
switch (mySelectionMode) {
case Mode_Normal:
if (isMultiple == Standard_False) {
ClearSelected();
myMapObjects[NIS_Drawer::Draw_Hilighted] = aMap;
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
const Standard_Integer anID = anIter.Key();
selectObj (myObjects(anID), anID);
}
} else {
case Mode_Additive:
if (isModifierUsed == Standard_False) {
if (mySelectionMode == Mode_Normal)
{
ClearSelected();
myMapObjects[NIS_Drawer::Draw_Hilighted] = aMap;
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
const Standard_Integer anID = anIter.Key();
selectObj (myObjects(anID), anID);
}
}
else
{
aMap.Subtract (myMapObjects[NIS_Drawer::Draw_Hilighted]);
myMapObjects[NIS_Drawer::Draw_Hilighted].Unite (aMap);
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
const Standard_Integer anID = anIter.Key();
selectObj (myObjects(anID), anID);
}
}
} else { // the modifier is pressed
TColStd_PackedMapOfInteger aMapSub;
aMapSub.Intersection(aMap, myMapObjects[NIS_Drawer::Draw_Hilighted]);
aMap.Subtract (myMapObjects[NIS_Drawer::Draw_Hilighted]);
@@ -558,14 +624,6 @@ void NIS_InteractiveContext::ProcessSelection
}
}
break;
case Mode_Additive:
aMap.Subtract (myMapObjects[NIS_Drawer::Draw_Hilighted]);
myMapObjects[NIS_Drawer::Draw_Hilighted].Unite (aMap);
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
const Standard_Integer anID = anIter.Key();
selectObj (myObjects(anID), anID);
}
break;
case Mode_Exclusive:
aMap.Intersect (myMapObjects[NIS_Drawer::Draw_Hilighted]);
myMapObjects[NIS_Drawer::Draw_Hilighted].Subtract (aMap);
@@ -650,58 +708,78 @@ void NIS_InteractiveContext::SetSelected
//=======================================================================
//function : selectObject
//purpose :
//purpose :
//=======================================================================
Standard_Real NIS_InteractiveContext::selectObject
(Handle_NIS_InteractiveObject& theSel,
NCollection_List<DetectedEnt>& theDetected,
//(Handle_NIS_InteractiveObject& theSel,
(NCollection_List<DetectedEnt>& theDetected,
const gp_Ax1& theAxis,
const Standard_Real theOver,
const Standard_Boolean isOnlySel) const
const Standard_Boolean isOnlySel,
const NIS_SelectFilter::Event theEvent) const
{
static const Standard_Real anInfiniteDist = 0.5 * RealLast();
Standard_Real aMinDist(anInfiniteDist);
if (mySelectionMode != Mode_NoSelection || isOnlySel == Standard_False)
if (mySelectionMode == Mode_NoSelection && isOnlySel)
{
DetectedEnt anEnt;
NCollection_SparseArray <Handle_NIS_InteractiveObject>::ConstIterator
anIter(myObjects);
for (; anIter.More(); anIter.Next()) {
const Handle(NIS_InteractiveObject)& anObj = anIter.Value();
if (anObj.IsNull() == Standard_False)
if (anObj->IsDisplayed() &&
(!myMapNonSelectableObjects.Contains (anObj->ID()) ||
isOnlySel == Standard_False))
return anInfiniteDist;
}
Standard_Real aMinDist = anInfiniteDist;
DetectedEnt anEnt;
for (NCollection_SparseArray <Handle_NIS_InteractiveObject>::ConstIterator anIter (myObjects);
anIter.More(); anIter.Next())
{
const Handle(NIS_InteractiveObject)& anObj = anIter.Value();
// check object is selectable
if (anObj.IsNull() || !anObj->IsDisplayed()
|| (isOnlySel && myMapNonSelectableObjects.Contains (anObj->ID()))
// early-out - check the intersection with the bounding box
|| anObj->IsOut (theAxis, Standard_False, theOver))
{
continue;
}
// pass the object through the SelectFilter if available
if (!mySelectFilter.IsNull())
{
if (!mySelectFilter->ActsOn (anObj->DynamicType())
|| !mySelectFilter->IsOk (anObj.operator->(), theAxis,
theOver, theEvent))
{
continue;
}
}
anEnt.Dist = anObj->Intersect (theAxis, theOver);
if (anEnt.Dist < anInfiniteDist)
{
// insert the detected entity in the sorted list
anEnt.PObj = anObj.operator->();
anEnt.Prio = anObj->GetDrawer()->Priority();
NCollection_List<DetectedEnt>::Iterator anIterD(theDetected);
for (; anIterD.More(); anIterD.Next())
{
const DetectedEnt& anEntOther = anIterD.Value();
if (anEnt.Dist < anEntOther.Dist - Precision::Confusion()
|| (anEnt.Prio > anEntOther.Prio
&& anEnt.Dist < anEntOther.Dist + Precision::Confusion())
|| (anEnt.Prio == anEntOther.Prio
&& anEnt.Dist <= anEntOther.Dist))
{
// Pass the object through the SelectFilter if available
if (mySelectFilter.IsNull() == Standard_False)
if (mySelectFilter->IsOk (anObj.operator->()) == Standard_False)
continue;
// Check the intersection with the box
const Bnd_B3f& aBox = anObj->GetBox();
if (aBox.IsOut (theAxis, Standard_False, theOver) == Standard_False)
{
anEnt.Dist = anObj->Intersect (theAxis, theOver);
if (anEnt.Dist < anInfiniteDist) {
anEnt.PObj = anObj.operator->();
// Insert the detected entity in the sorted list
NCollection_List<DetectedEnt>::Iterator anIterD(theDetected);
for (; anIterD.More(); anIterD.Next()) {
if (anEnt.Dist < anIterD.Value().Dist) {
theDetected.InsertBefore(anEnt, anIterD);
break;
}
}
if (anIterD.More() == Standard_False)
theDetected.Append(anEnt);
if (anEnt.Dist < aMinDist) {
aMinDist = anEnt.Dist;
theSel = anObj;
}
}
}
theDetected.InsertBefore (anEnt, anIterD);
break;
}
}
if (!anIterD.More())
{
theDetected.Append (anEnt);
}
aMinDist = Min (aMinDist, anEnt.Dist);
}
}
return aMinDist;
@@ -754,9 +832,12 @@ Standard_Boolean NIS_InteractiveContext::selectObjects
if (anObj.IsNull() == Standard_False)
if (anObj->IsDisplayed()) {
// Pass the object through the SelectFilter if available
if (mySelectFilter.IsNull() == Standard_False)
if (mySelectFilter.IsNull() == Standard_False) {
if (mySelectFilter->ActsOn(anObj->DynamicType()) == Standard_False)
continue;
if (mySelectFilter->IsOk (anObj.operator->()) == Standard_False)
continue;
}
// Check the intersection with the box
const Bnd_B3f& aBox = anObj->GetBox();
if (aBox.IsIn (theBox, theTrf)) {
@@ -798,9 +879,12 @@ Standard_Boolean NIS_InteractiveContext::selectObjects
if (anObj.IsNull() == Standard_False)
if (anObj->IsDisplayed()) {
// Pass the object through the SelectFilter if available
if (mySelectFilter.IsNull() == Standard_False)
if (mySelectFilter.IsNull() == Standard_False) {
if (!mySelectFilter->ActsOn(anObj->DynamicType()))
continue;
if (mySelectFilter->IsOk (anObj.operator->()) == Standard_False)
continue;
}
// Comvert 3d box to 2d one
const Bnd_B3f &aBox = anObj->GetBox();
@@ -846,9 +930,11 @@ void NIS_InteractiveContext::deselectObj
{
if (theObj.IsNull() == Standard_False) {
const Handle(NIS_Drawer)& aDrawer = theObj->GetDrawer();
NIS_Drawer::DrawType aType = theObj->myBaseType;
if (theObj->IsTransparent()) {
myMapObjects[NIS_Drawer::Draw_Transparent].Add(theID);
aDrawer->SetUpdated(NIS_Drawer::Draw_Transparent);
aType = NIS_Drawer::Draw_Transparent;
} else if (theObj->myBaseType == NIS_Drawer::Draw_Top) {
myMapObjects[NIS_Drawer::Draw_Top].Add(theID);
aDrawer->SetUpdated(NIS_Drawer::Draw_Top);
@@ -856,8 +942,8 @@ void NIS_InteractiveContext::deselectObj
myMapObjects[NIS_Drawer::Draw_Normal].Add(theID);
aDrawer->SetUpdated(NIS_Drawer::Draw_Normal);
}
theObj->myDrawType = aType;
aDrawer->SetUpdated(NIS_Drawer::Draw_Hilighted);
theObj->myDrawType = theObj->myBaseType;
}
}
@@ -872,7 +958,7 @@ void NIS_InteractiveContext::selectObj
{
if (theObj.IsNull() == Standard_False) {
const Handle(NIS_Drawer)& aDrawer = theObj->GetDrawer();
if (theObj->IsTransparent()) {
if (theObj->myDrawType == NIS_Drawer::Draw_Transparent) {
myMapObjects[NIS_Drawer::Draw_Transparent].Remove(theID);
aDrawer->SetUpdated(NIS_Drawer::Draw_Transparent);
} else if (theObj->myDrawType == NIS_Drawer::Draw_Top) {
@@ -882,8 +968,8 @@ void NIS_InteractiveContext::selectObj
myMapObjects[NIS_Drawer::Draw_Normal].Remove(theID);
aDrawer->SetUpdated(NIS_Drawer::Draw_Normal);
}
aDrawer->SetUpdated(NIS_Drawer::Draw_Hilighted);
theObj->myDrawType = NIS_Drawer::Draw_Hilighted;
aDrawer->SetUpdated(NIS_Drawer::Draw_Hilighted);
}
}
@@ -945,9 +1031,17 @@ Handle_NIS_Allocator NIS_InteractiveContext::compactObjects()
// Check if the memory used by objects has to be compacted.
const Standard_Size nAllocated = myAllocator->NAllocated();
if (nAllocated > 1024*1024) {
if (nAllocated > 4 * aSizeAlloc) {
const Standard_Size nFreed = myAllocator->NFreed();
if ((nFreed * 5) / 3 > nAllocated || nFreed > 20*1024*1024)
Standard_Boolean toCompact = (nFreed * 5) / 2 > nAllocated;
if (toCompact)
{
// evaluate if there is enough memory to allocate clones
const Standard_Size nUsed = nAllocated - nFreed;
if (!CanBeAllocated(nUsed, aSizeAlloc))
toCompact = Standard_False;
}
if (toCompact)
{
for (anIterV.Init(myViews); anIterV.More(); anIterV.Next()) {
const Handle(NIS_View)& aView = anIterV.Value();
@@ -958,7 +1052,7 @@ Handle_NIS_Allocator NIS_InteractiveContext::compactObjects()
}
// Compact the memory: clone all objects to a new allocator, release
// the old allocator instance.
aNewAlloc = new NIS_Allocator;
aNewAlloc = new NIS_Allocator(aSizeAlloc);
NCollection_SparseArray<Handle_NIS_InteractiveObject>::Iterator
anIter(myObjects);
for (; anIter.More(); anIter.Next()) {
@@ -974,6 +1068,18 @@ Handle_NIS_Allocator NIS_InteractiveContext::compactObjects()
return aNewAlloc;
}
//=======================================================================
//function : CompactObjects
//purpose :
//=======================================================================
void NIS_InteractiveContext::CompactObjects()
{
const Handle_NIS_Allocator aNewAlloc = compactObjects();
if (aNewAlloc.IsNull() == Standard_False)
myAllocator = aNewAlloc;
}
//=======================================================================
//function : markAllDrawersUpdated
//purpose :
@@ -992,3 +1098,54 @@ void markAllDrawersUpdated (const NCollection_Map<Handle_NIS_Drawer>& lstDrv)
}
}
}
//=======================================================================
//function : GetObjectsOfType
//purpose :
//=======================================================================
const TColStd_PackedMapOfInteger& NIS_InteractiveContext
::GetObjectsOfType (const NIS_Drawer::DrawType theDrawType) const
{
// notice that there are no map for Draw_DynHilighted type!
Standard_OutOfRange_Raise_if (theDrawType < NIS_Drawer::Draw_Normal ||
theDrawType >= NIS_Drawer::Draw_DynHilighted,
"NIS_InteractiveContext::GetObjectsOfType: Irrelevant DrawType");
return myMapObjects[theDrawType];
}
//=======================================================================
//function : CanBeAllocated
//purpose :
//=======================================================================
Standard_Boolean CanBeAllocated(const Standard_Size theNeedTotal,
const Standard_Size theBlockSize)
{
NCollection_List<void*> aList;
Standard_Size aNAlloc = 0;
while (aNAlloc < theNeedTotal)
{
#ifdef WNT
void* pMem = VirtualAlloc(NULL, theBlockSize, MEM_RESERVE, PAGE_READWRITE);
#else
void* pMem = malloc(theBlockSize);
#endif
if (!pMem)
{
break;
}
aNAlloc += theBlockSize;
aList.Append(pMem);
}
NCollection_List<void*>::Iterator it(aList);
for (; it.More(); it.Next())
{
#ifdef WNT
VirtualFree(it.Value(), 0, MEM_RELEASE);
#else
free(it.Value());
#endif
}
return aNAlloc >= theNeedTotal;
}

View File

@@ -34,6 +34,9 @@ class NIS_View;
class Bnd_B3f;
class Bnd_B2f;
/**
@defgroup nis_library NIS Library (New Interactive Services)
*/
/**
* InteractiveContext is the central NIS structure that stores and manages
* all NIS_InteractiveObject instances as well as the Drawers for their
@@ -122,6 +125,7 @@ class Bnd_B2f;
* <p>
* This mechanism works when either UpdateViews() or RebuildViews() is called
* from time to time, only these two methods can call compactObjects().
* @ingroup nis_library
*/
class NIS_InteractiveContext : public Standard_Transient
@@ -167,6 +171,12 @@ class NIS_InteractiveContext : public Standard_Transient
Standard_EXPORT const Handle_NIS_InteractiveObject&
GetObject (const Standard_Integer theID) const;
/**
* Access map of objects with specified draw type.
*/
Standard_EXPORT const TColStd_PackedMapOfInteger&
GetObjectsOfType (const NIS_Drawer::DrawType theType) const;
/**
* Query the total number of InteractiveObject instances. This number can be
* smaller than the greatest object ID, therefore you should not iterate till
@@ -193,6 +203,13 @@ class NIS_InteractiveContext : public Standard_Transient
GetDrawers () const
{ return NCollection_Map<Handle_NIS_Drawer>::Iterator(myDrawers); }
/**
* Access to views.
*/
inline NCollection_List<Handle_NIS_View>::Iterator
GetViews () const
{ return NCollection_List<Handle_NIS_View>::Iterator(myViews); }
// ================ BEGIN Mangement of Objects ================
///@name Management of Objects
//@{
@@ -364,14 +381,16 @@ class NIS_InteractiveContext : public Standard_Transient
* This method does not update the views.
* @param O
* Object to be selected or deselected
* @param isMultiple
* If True, then the objects are not automatically deselected.
* @param isModifierUsed
* If True, then the modification of the current selection mode happens.
* E.g. if True and selection mode is normal, the objects are not automatically
* deselected.
* @return
* True if the selection status has been changed, False if nothing changed
*/
Standard_EXPORT Standard_Boolean
ProcessSelection(const Handle_NIS_InteractiveObject& O,
const Standard_Boolean isMultiple
const Standard_Boolean isModifierUsed
= Standard_False);
/**
@@ -380,11 +399,13 @@ class NIS_InteractiveContext : public Standard_Transient
* selection mode is respected.
* @param map
* Container of IDs of objects to be processed
* @param isMultiple
* If True, then the objects are not automatically deselected.
* @param isModifierUsed
* If True, then the modification of the current selection mode happens.
* E.g. if True and selection mode is normal, the objects are not automatically
* deselected.
*/
Standard_EXPORT void ProcessSelection(const TColStd_PackedMapOfInteger& map,
const Standard_Boolean isMultiple
const Standard_Boolean isModifierUsed
= Standard_False);
/**
@@ -464,6 +485,11 @@ class NIS_InteractiveContext : public Standard_Transient
inline void SetShareDrawList (Standard_Boolean isShare)
{ myIsShareDrawList = isShare; }
/**
* Compresses the allocated memory.
*/
Standard_EXPORT void CompactObjects();
//@}
// ====== END Selection API ================
@@ -471,19 +497,19 @@ class NIS_InteractiveContext : public Standard_Transient
//! Structure referencing one detected (picked) interactive entity.
struct DetectedEnt
{
Standard_Real Dist; //!< Distance on the view direction
NIS_InteractiveObject* PObj; //!< Pointer to interactive object
Standard_Real Dist; //!< Distance on the view direction
NIS_InteractiveObject* PObj; //!< Pointer to interactive object
NIS_Drawer::PriorityLevel Prio; //!< Selected object drawer priority
};
// ---------- PROTECTED METHODS ----------
Standard_EXPORT void redraw (const Handle_NIS_View& theView,
const NIS_Drawer::DrawType theType);
Standard_EXPORT void redraw (const Handle_NIS_View& theView,
const NIS_Drawer::DrawType theType,
const NIS_Drawer::PriorityLevel thePriority);
/**
* Detect the object selected by the given ray.
* @param theSel
* <tt>[out]</tt> The selected object that has the lowest ray distance.
* @param theDet
* <tt>[out]</tt> Sorted list of all detected objects with ray distances
* @param theAxis
@@ -493,16 +519,17 @@ class NIS_InteractiveContext : public Standard_Transient
* @param isOnlySelectable
* If False, any displayed object can be picked, otherwise only selectable
* ones.
* @param theEvent
* Describes the evernt that invokes this method.
* @return
* The ray distance of the intersection point between the ray and theSel.
*/
Standard_EXPORT Standard_Real
selectObject (Handle_NIS_InteractiveObject& theSel,
NCollection_List<DetectedEnt>& theDet,
const gp_Ax1& theAxis,
const Standard_Real theOver,
const Standard_Boolean isOnlySelectable
= Standard_True) const;
selectObject (NCollection_List<DetectedEnt>& theDet,
const gp_Ax1& theAxis,
const Standard_Real theOver,
const Standard_Boolean isOnlySelectable = Standard_True,
const NIS_SelectFilter::Event theEvent = NIS_SelectFilter::Indefinite) const;
/**
* Build a list of objects that are inside or touched by an oriented box.
@@ -572,6 +599,8 @@ private:
Handle_NIS_Allocator
compactObjects ();
void detachView (NCollection_List<Handle_NIS_View>::Iterator&);
private:
// ---------- PRIVATE FIELDS ----------
@@ -611,6 +640,11 @@ private:
*/
TColStd_PackedMapOfInteger myMapObjects[4];
/**
* Number of drawers per priority.
*/
Standard_Integer myPriorities[NIS_Drawer::Priority_LevelsNb];
/**
* Objects contained in this map are ignored by SetSelected methods,
* these objects are not selectable.

View File

@@ -41,7 +41,8 @@ const Handle_NIS_Drawer& NIS_InteractiveObject::SetDrawer
const Standard_Boolean setUpdated)
{
NIS_InteractiveContext * aCtx = theDrawer->GetContext();
if (myDrawer.IsNull() == Standard_False) {
if (myDrawer.IsNull() == Standard_False)
{
if (aCtx == 0L)
{
aCtx = myDrawer->GetContext();
@@ -65,9 +66,12 @@ const Handle_NIS_Drawer& NIS_InteractiveObject::SetDrawer
{
// Move the Object from the old drawer to the new one.
if (myDrawer.IsNull() == Standard_False)
{
myDrawer->removeObject(this, Standard_True);
}
myDrawer = aDrawer;
++aCtx->myPriorities[myDrawer->Priority()];
myDrawer->addObject(this, aCtx->myIsShareDrawList, Standard_True);
}
if (setUpdated)
@@ -107,7 +111,7 @@ void NIS_InteractiveObject::SetTransparency (const Standard_Real theValue)
(aCtx == 0L, "NIS_InteractiveObject::SetTransparency: "
"NULL drawer context");
if (IsTransparent()) {
if (myDrawType == NIS_Drawer::Draw_Normal) {
if (myDrawType != NIS_Drawer::Draw_Transparent) {
aCtx->myMapObjects[NIS_Drawer::Draw_Transparent].Add(myID);
aCtx->myMapObjects[NIS_Drawer::Draw_Normal].Remove(myID);
myDrawType = NIS_Drawer::Draw_Transparent;
@@ -117,7 +121,7 @@ void NIS_InteractiveObject::SetTransparency (const Standard_Real theValue)
if (myDrawType == NIS_Drawer::Draw_Transparent) {
aCtx->myMapObjects[NIS_Drawer::Draw_Normal].Add(myID);
aCtx->myMapObjects[NIS_Drawer::Draw_Transparent].Remove(myID);
myDrawType = NIS_Drawer::Draw_Normal;
myDrawType = myBaseType;
}
myDrawer->SetUpdated (NIS_Drawer::Draw_Transparent);
}
@@ -238,3 +242,56 @@ void NIS_InteractiveObject::SetSelectable (const Standard_Boolean isSel) const
}
}
}
//=======================================================================
//function : SetColor
//purpose : Set the color for presentation.
//=======================================================================
void NIS_InteractiveObject::SetColor (const Quantity_Color& theColor,
const NIS_Drawer::DrawType theType)
{
const Handle(NIS_Drawer) aDrawer = DefaultDrawer(0L);
aDrawer->Assign (GetDrawer());
aDrawer->SetColor(theType, theColor);
SetDrawer (aDrawer);
}
//=======================================================================
//function : GetColor
//purpose : Get the color for presentation.
//=======================================================================
Quantity_Color NIS_InteractiveObject::GetColor
(const NIS_Drawer::DrawType theType) const
{
return myDrawer.IsNull() ? Quantity_Color() : myDrawer->GetColor(theType);
}
//=======================================================================
//function : SetHilightColors
//purpose : Set the colors for hilight and dynamic hilight presentations.
//=======================================================================
void NIS_InteractiveObject::SetHilightColors (const Quantity_Color& theHLColor,
const Quantity_Color& theDHLColor)
{
const Handle(NIS_Drawer) aDrawer = DefaultDrawer(0L);
aDrawer->Assign (GetDrawer());
aDrawer->SetColor(NIS_Drawer::Draw_Hilighted, theHLColor);
aDrawer->SetColor(NIS_Drawer::Draw_DynHilighted, theDHLColor);
SetDrawer (aDrawer);
}
//=======================================================================
//function : IsOut
//purpose : Check the intersection a line/ray with the bounding box of object.
//=======================================================================
Standard_Boolean NIS_InteractiveObject::IsOut
(const gp_Ax1& theAxis,
const Standard_Boolean isRay,
const Standard_Real theOver)
{
return GetBox().IsOut (theAxis, isRay, theOver);
}

View File

@@ -48,7 +48,7 @@
* method should not be called by any custom code, it is used internally by
* NIS algorithms (in NIS_InteractiveContext::Display() for instance). If you
* develop your own InteractiveObject type, you will need to call SetDrawer
* whenever you change the visual aspect, for example:
* whenever you change a visual aspect, for example:
* @code
* void MyIOClass::SetColor (const Quantity_Color& theColor);
* {
@@ -74,7 +74,7 @@
* Parameter theOver provides the tolerance for intersection of thin
* geometries (lines, vertices)</li>
* <li>Intersect (theBox, theTrsf, isFullIn) : check if the interactive object
* intersects with a 3D box. Transformation 'theTrf' is the <b>inverse</b>
* intersects with a 3D box. Transformation 'theTrsf' is the <b>inverse</b>
* box transformation, so it is applied to the interactive object rather
* than to the 3D box (3D box stays axis-aligned during intersection
* test). Parameter IsFullIn defines the condition for the result: if
@@ -93,9 +93,9 @@
* because NIS_InteractiveContext should completely manage all its objects,
* meaning that it destroys/reallocates them automatically. To support that,
* the virtual method Clone() should be correctly defined for every interactive
* object subtype. Supposing that MyIOClass inherits MyBaseIOBase :
* object subtype. Supposing that MyIOClass inherits MyIOBase :
* @code
* void MyIOCalss::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
* void MyIOClass::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
* Handle_NIS_InteractiveObject& theDest) const
* {
* Handle(MyIOClass) aNewObj;
@@ -118,6 +118,7 @@
* stored as a pointer. It can accommodate an integer/float/boolean value or
* a pointer to some structure. This attribute is NOT automatically destroyed
* with the InteractiveObject.
* @ingroup nis_library
*/
class NIS_InteractiveObject : public Standard_Transient
@@ -341,6 +342,50 @@ class NIS_InteractiveObject : public Standard_Transient
Intersect (const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean isFull) const;
/**
* Set the color for presentation.
* @param theColor
* New color to use for the presentation.
* @param theType
* Draw type for which the color is defined
*/
Standard_EXPORT virtual void SetColor
(const Quantity_Color& theColor,
const NIS_Drawer::DrawType theType = NIS_Drawer::Draw_Normal);
/**
* Set the color for hilighted presentation.
* @param theColor
* New color to use for the presentation.
*/
inline void SetHilightColor (const Quantity_Color& theColor)
{
return SetColor (theColor, NIS_Drawer::Draw_Hilighted);
}
/**
* Set the color for dynamic hilight presentation.
* @param theColor
* New color to use for the presentation.
*/
inline void SetDynHilightColor (const Quantity_Color& theColor)
{
SetColor (theColor, NIS_Drawer::Draw_DynHilighted);
}
/**
* Set the colors for hilight and dynamic hilight presentations.
*/
Standard_EXPORT void SetHilightColors(const Quantity_Color& theHLColor,
const Quantity_Color& theDHLColor);
/**
* Get Normal, Transparent or Hilighted color of the presentation.
* @param theType
* The draw type, for which the color is retrieved.
*/
Standard_EXPORT Quantity_Color GetColor
(const NIS_Drawer::DrawType theType = NIS_Drawer::Draw_Normal) const;
/**
* Set the pointer to custom (arbitrary) data associated with the Object.
@@ -354,6 +399,15 @@ class NIS_InteractiveObject : public Standard_Transient
inline void * GetAttribute () const
{ return myAttributePtr; }
/**
* Check the intersection a line/ray with the bounding box of object.
* @see Bnd_B3f::IsOut().
*/
Standard_EXPORT virtual Standard_Boolean
IsOut (const gp_Ax1& theAxis,
const Standard_Boolean isRay = 0,
const Standard_Real theOver = 0.0);
protected:
// ---------- PROTECTED METHODS ----------

281
src/NIS/NIS_Line.cxx Normal file
View File

@@ -0,0 +1,281 @@
// File: NIS_Line.cpp
// Created: 11.05.12
// Author: Natalia Kopnova
// Copyright: LPKF Laser and Electronics AG 2012
#include <NIS_Line.hxx>
#include <NIS_LineDrawer.hxx>
#include <NIS_InteractiveContext.hxx>
#include <Precision.hxx>
#include <UnitsAPI.hxx>
IMPLEMENT_STANDARD_HANDLE (NIS_Line, NIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT (NIS_Line, NIS_InteractiveObject)
#define MAX_WIDTH 500000.
//=======================================================================
//function : NIS_Line
//purpose : Constructor
//=======================================================================
NIS_Line::NIS_Line(const gp_Ax1& theAxis)
{
// SetAttributeId(0);
Init(theAxis);
}
//=======================================================================
//function : Init
//purpose : Re-initialize the internal structures, re-compute the presentation
//=======================================================================
void NIS_Line::Init(const gp_Ax1& theAxis)
{
myLine = theAxis;
const Handle(NIS_LineDrawer) aDrawer =
Handle(NIS_LineDrawer)::DownCast(GetDrawer());
// Standard_Real aLength = UnitsAPI::AnyToLS( 250000., "mm" );
const gp_XYZ aLength = (0.5 * MAX_WIDTH) * myLine.Direction().XYZ();
gp_XYZ aPoint1;
if(aDrawer.IsNull())
{
aPoint1 = myLine.Location().XYZ();
}
else
{
if ( aDrawer->myLineType == NIS_LT_Line )
{
aPoint1 = myLine.Location().XYZ() - aLength;
}
else
{
aPoint1 = myLine.Location().XYZ();
}
}
myPoint1[0] = static_cast<Standard_ShortReal> (aPoint1.X());
myPoint1[1] = static_cast<Standard_ShortReal> (aPoint1.Y());
myPoint1[2] = static_cast<Standard_ShortReal> (aPoint1.Z());
const gp_XYZ aPoint2 = myLine.Location().XYZ() + aLength;
myPoint2[0] = static_cast<Standard_ShortReal> (aPoint2.X());
myPoint2[1] = static_cast<Standard_ShortReal> (aPoint2.Y());
myPoint2[2] = static_cast<Standard_ShortReal> (aPoint2.Z());
// setIsUpdateBox(Standard_True);
}
//=======================================================================
//function : ~NIS_Line
//purpose : Destructor
//=======================================================================
NIS_Line::~NIS_Line()
{
}
//=======================================================================
//function : DefaultDrawer
//purpose :
//=======================================================================
NIS_Drawer* NIS_Line::DefaultDrawer (NIS_Drawer* theDrawer) const
{
if (theDrawer == 0L)
{
return new NIS_LineDrawer(Quantity_NOC_YELLOW);
}
NIS_LineDrawer* aDrawer = static_cast<NIS_LineDrawer*>(theDrawer);
return aDrawer;
}
//=======================================================================
//function : Clone
//purpose :
//=======================================================================
void NIS_Line::Clone
(const Handle_NCollection_BaseAllocator& theAlloc,
Handle_NIS_InteractiveObject& theDest) const
{
Handle(NIS_Line) aNewObj;
if (theDest.IsNull())
{
aNewObj = new NIS_Line(myLine);
theDest = aNewObj;
}
else
{
aNewObj = reinterpret_cast<NIS_Line*> (theDest.operator->());
aNewObj->myLine = myLine;
aNewObj->myPoint1[0] = myPoint1[0];
aNewObj->myPoint1[1] = myPoint1[1];
aNewObj->myPoint1[2] = myPoint1[2];
aNewObj->myPoint2[0] = myPoint2[0];
aNewObj->myPoint2[1] = myPoint2[1];
aNewObj->myPoint2[2] = myPoint2[2];
}
NIS_InteractiveObject::Clone(theAlloc, theDest);
}
//=======================================================================
//function : SetLineWidth
//purpose : Set the line width in pixels.
//=======================================================================
void NIS_Line::SetLineWidth (const Standard_Real theSize)
{
const Handle(NIS_LineDrawer) aDrawer =
static_cast<NIS_LineDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
aDrawer->myLineWidth = static_cast<Standard_ShortReal>(theSize);
SetDrawer(aDrawer);
}
//=======================================================================
//function : SetLineStyle
//purpose : Set the style of line presentation.
//=======================================================================
void NIS_Line::SetLineStyle (const NIS_LineStyle theStyle)
{
const Handle(NIS_LineDrawer) aDrawer =
static_cast<NIS_LineDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
aDrawer->myType = static_cast<Standard_Integer>(theStyle);
SetDrawer(aDrawer);
}
//=======================================================================
//function : SetLineType
//purpose : Set the type of line presentation.
//=======================================================================
void NIS_Line::SetLineType (const NIS_LineType theType)
{
const Handle(NIS_LineDrawer) aDrawer =
static_cast<NIS_LineDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
aDrawer->myLineType = static_cast<Standard_Integer>(theType);
SetDrawer(aDrawer);
}
//=======================================================================
//function : SetInvertColor
//purpose : Indicates whether to draw line depending on underlying objects
//=======================================================================
void NIS_Line::SetInvertColor (const Standard_Boolean theInvert)
{
const Handle(NIS_LineDrawer) aDrawer =
static_cast<NIS_LineDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
aDrawer->myInvertColor = static_cast<Standard_Boolean>(theInvert);
SetDrawer(aDrawer);
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Boolean NIS_Line::Intersect
(const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean /*isFullIn*/) const
{
return !theBox.IsOut(myLine.Transformed(theTrf));
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Real NIS_Line::Intersect(const gp_Ax1& theAxis,
const Standard_Real theOver) const
{
Standard_Real aResult (RealLast());
const Standard_Real anOver2 = theOver*theOver;
const gp_XYZ anAxisDir = theAxis.Direction().XYZ();
const gp_XYZ aDir = myLine.Direction().XYZ();
const gp_XYZ aDirN = aDir ^ anAxisDir; // normal direction to both lines
// vector between 'start' points of two lines
const gp_XYZ aDelta = myLine.Location().XYZ() - theAxis.Location().XYZ();
Standard_Real aMod2 = aDirN.SquareModulus();
if (aMod2 < Precision::Confusion() * 0.001)
{
// lines are parallel
if ( (aDelta ^ anAxisDir).SquareModulus() < anOver2 )
{
aResult = aDelta * anAxisDir;
}
}
else
{
// distance between two lines
Standard_Real aDist = aDelta * aDirN;
if (aDist * aDist < anOver2 * aMod2)
{
aResult = aDelta * anAxisDir;
}
}
return aResult;
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Boolean NIS_Line::Intersect
(const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean /*isFullIn*/) const
{
Standard_Boolean aResult = Standard_False;
gp_Ax1 aLine = myLine.Transformed(theTrf);
const gp_XYZ aLoc = aLine.Location().XYZ();
const gp_XYZ aDir = aLine.Direction().XYZ();
gp_XY aDir2d(aDir.X(), aDir.Y());
Standard_Real aDist = aDir2d.SquareModulus();
if (aDist > Precision::Confusion())
{
aDir2d.Divide(sqrt(aDist));
// check whether all polygon points in in the same side of line
// Line is presented in form Ax + By + C = 0
Standard_Real A = aDir.Y();
Standard_Real B = -aDir.X();
Standard_Real C = -(A*aLoc.X() + B*aLoc.Y());
gp_XY aPoint = thePolygon.Last();
Standard_Real aSigned[2];
aSigned[0] = A*aPoint.X() + B*aPoint.Y() + C;
NCollection_List<gp_XY>::Iterator anIter(thePolygon);
for (; anIter.More(); anIter.Next())
{
aPoint = anIter.Value();
aSigned[1] = A*aPoint.X() + B*aPoint.Y() + C;
if (aSigned[0] * aSigned[1] <= Precision::Confusion())
{
aResult = Standard_True;
break;
}
aSigned[0] = aSigned[1];
}
}
return aResult;
}

213
src/NIS/NIS_Line.hxx Normal file
View File

@@ -0,0 +1,213 @@
// File: NIS_Line.h
// Created: 11.05.12
// Author: Natalia Kopnova
// Copyright: LPKF Laser and Electronics AG 2012
#ifndef NIS_Line_HeaderFile
#define NIS_Line_HeaderFile
#include <NIS_InteractiveObject.hxx>
#include <NIS_LineDrawer.hxx>
#include <gp_Ax1.hxx>
class Handle_NIS_InteractiveContext;
//! Line style enumeration
//! @ingroup aisobject
enum NIS_LineStyle {
NIS_LS_Solid = 0,
NIS_LS_Dash,
NIS_LS_Dot,
NIS_LS_DotDash,
NIS_LS_DoubleDotDash
};
//! Line type enumeration
//! @ingroup aisobject
enum NIS_LineType {
NIS_LT_Line = 0,
NIS_LT_Ray
};
/**
* Interactive Object for 2D/3D lines
* @ingroup aisobject
*/
class NIS_Line : public NIS_InteractiveObject
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
*/
Standard_EXPORT NIS_Line (const gp_Ax1& theAxis);
/**
* Destructor.
*/
Standard_EXPORT virtual ~NIS_Line ();
/**
* Re-initialize the internal structures, re-compute the presentation
*/
Standard_EXPORT void Init (const gp_Ax1& theAxis);
/**
* Create a default drawer instance.
*/
Standard_EXPORT virtual NIS_Drawer*
DefaultDrawer (NIS_Drawer*) const;
/**
* Method required by NIS_InteractiveContext.
*/
Standard_EXPORT virtual void
Clone (const Handle_NCollection_BaseAllocator&,
Handle_NIS_InteractiveObject&) const;
/**
* Set the line width in pixels.
* @param theSize
* New line width to use for the presentation.
*/
Standard_EXPORT void SetLineWidth (const Standard_Real theSize);
/**
* Set the line style.
* @param theStyle
* Line style to be used for the presentation.
*/
Standard_EXPORT void SetLineStyle (const NIS_LineStyle theStyle);
/**
* Set the line type.
* @param theType
* Line type to be used for the presentation.
*/
Standard_EXPORT void SetLineType (const NIS_LineType theType);
/**
* Set whether line color should be inverted depending on color of
* underlying objects.
* @param theInvert
* True to invert color.
*/
Standard_EXPORT void SetInvertColor (const Standard_Boolean theInvert);
/**
* Intersect the InteractiveObject geometry with an oriented box.
* @param theBox
* 3D box of selection
* @param theTrf
* Position/Orientation of the box.
* @param isFull
* True if full inclusion is required, False - if partial.
* @return
* True if the InteractiveObject geometry intersects the box or is inside it
*/
Standard_EXPORT virtual Standard_Boolean
Intersect (const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean isFull)const;
/**
* Intersect the InteractiveObject geometry with a line/ray.
* @param theAxis
* The line or ray in 3D space.
* @param theOver
* Half-thickness of the selecting line.
* @return
* If the return value is more than 0.1*RealLast() then no intersection is
* detected. Otherwise returns the coordinate of thePnt on the ray. May be
* negative.
*/
Standard_EXPORT virtual Standard_Real
Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver)const;
/**
* Intersect the InteractiveObject geometry with a selection polygon.
* @param thePolygon
* the list of vertices of a free-form closed polygon without
* self-intersections. The last point should not coincide with the first
* point of the list. Any two neighbor points should not be confused.
* @param theTrf
* Position/Orientation of the polygon.
* @param isFull
* True if full inclusion is required, False - if partial.
* @return
* True if the InteractiveObject geometry intersects the polygon or is
* inside it
*/
Standard_EXPORT virtual Standard_Boolean Intersect
(const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean isFull) const;
/**
* Store an integer value as attribute of the Object.
*/
inline void SetAttributeId (const Standard_Integer theId)
{
SetAttribute (reinterpret_cast <void*> (theId));
}
/**
* Returns the attribute value previously stored using SetAttributeId.
* Value 0 signifies that the AttributeId has not been set (as this is
* the constructor default value).
*/
inline Standard_Integer GetAttributeId () const
{
return reinterpret_cast <Standard_Integer> (GetAttribute());
}
/**
* Query the point coordinates.
*/
inline const Standard_ShortReal* GetPoint (const Standard_Integer ind) const
{
return (ind & 0x1) ? &myPoint1[0] : &myPoint2[0];
}
protected:
/**
* Create a 3D bounding box of the object.
* Does nothing because line is considered as infinitive
*/
Standard_EXPORT virtual void computeBox ()
{}
private:
// ---------- PRIVATE METHODS ----------
NIS_Line (const NIS_Line& theOther);
NIS_Line& operator= (const NIS_Line& theOther);
static Handle_NIS_LineDrawer defaultDrawer();
private:
// ---------- PRIVATE FIELDS ----------
gp_Ax1 myLine;
/**
* Array of coords
*/
Standard_ShortReal myPoint1[3];
Standard_ShortReal myPoint2[3];
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_Line)
friend class NIS_LineDrawer;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_Line, NIS_InteractiveObject)
#endif

176
src/NIS/NIS_LineDrawer.cxx Normal file
View File

@@ -0,0 +1,176 @@
// File: NIS_LineDrawer.cpp
// Created: 11.05.12
// Author: Natalia Kopnova
// Copyright: LPKF Laser and Electronics AG 2012
#include <NIS_LineDrawer.hxx>
#include <NIS_Line.hxx>
#ifdef _DEBUG
#include <Standard_ProgramError.hxx>
#endif
#ifdef WNT
#include <windows.h>
#include <GL/gl.h>
#endif
#define NUM_STYLES 5
static GLushort pattern[NUM_STYLES] = {
0xFFFF, // Solid
0xFFC0, // Dash
0xCCCC, // Dot
0xFF18, // DotDash
0xFF24 // DoubleDotDash
};
IMPLEMENT_STANDARD_HANDLE (NIS_LineDrawer, NIS_Drawer)
IMPLEMENT_STANDARD_RTTIEXT (NIS_LineDrawer, NIS_Drawer)
//=======================================================================
//function : NIS_LineDrawer
//purpose : Constructor
//=======================================================================
NIS_LineDrawer::NIS_LineDrawer(const Quantity_Color& theColor)
: myLineWidth(1.f), myType(0), myLineType(0), myInvertColor(Standard_False)
{
SetColor(Draw_Normal, theColor);
SetColor(Draw_Hilighted, Quantity_NOC_GRAY80);
SetColor(Draw_DynHilighted, Quantity_NOC_CYAN1);
}
//=======================================================================
//function : Assign
//purpose :
//=======================================================================
void NIS_LineDrawer::Assign (const Handle_NIS_Drawer& theOther)
{
if (theOther.IsNull() == Standard_False)
{
NIS_Drawer::Assign(theOther);
const Handle(NIS_LineDrawer)& anOther =
static_cast <const Handle(NIS_LineDrawer)&> (theOther);
myLineWidth = anOther->myLineWidth;
myType = anOther->myType;
myLineType = anOther->myLineType;
myInvertColor = anOther->myInvertColor;
}
}
//=======================================================================
//function : IsEqual
//purpose : Comparison of two Drawers (for Map impementation)
//=======================================================================
Standard_Boolean NIS_LineDrawer::IsEqual
(const Handle_NIS_Drawer& theOther) const
{
static const Standard_Real anEpsilon2 (1e-7);
Standard_Boolean aResult (Standard_False);
const Handle(NIS_LineDrawer) anOther =
Handle(NIS_LineDrawer)::DownCast(theOther);
if (NIS_Drawer::IsEqual(theOther))
{
aResult = ((anOther->myLineWidth - myLineWidth) *
(anOther->myLineWidth - myLineWidth) < 0.01 &&
anOther->myType == myType &&
anOther->myLineType == myLineType &&
anOther->myInvertColor == myInvertColor);
}
return aResult;
}
//=======================================================================
//function : BeforeDraw
//purpose :
//=======================================================================
void NIS_LineDrawer::BeforeDraw (const DrawType theType,
const NIS_DrawList& /*theDrawList*/)
{
Quantity_Parameter aValue[4];
aValue[3] = 1.; // opaque as default
Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
GLfloat aLineWidth (myLineWidth);
if (theType == Draw_DynHilighted)
{
aLineWidth = myLineWidth + 1.f;
}
if (myInvertColor)
{
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
}
else if (theType == Draw_Transparent)
{
aValue[3] = 1. - myTransparency;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
GetColor(theType).Values(aValue[0], aValue[1], aValue[2], bidTC);
glColor4d (aValue[0], aValue[1], aValue[2], aValue[3]);
glDisable(GL_LIGHTING);
if (myType > 0 && myType < NUM_STYLES)
{
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, pattern[myType]);
}
glLineWidth(aLineWidth);
}
//=======================================================================
//function : AfterDraw
//purpose :
//=======================================================================
void NIS_LineDrawer::AfterDraw (const DrawType theType,
const NIS_DrawList& /*theDrawList*/)
{
if (myInvertColor)
{
glDisable(GL_COLOR_LOGIC_OP);
}
else if (theType == Draw_Transparent)
{
glDisable(GL_BLEND);
}
if (myType > 0 && myType < NUM_STYLES)
{
glDisable(GL_LINE_STIPPLE);
}
}
//=======================================================================
//function : Draw
//purpose :
//=======================================================================
void NIS_LineDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
const DrawType /*theType*/,
const NIS_DrawList& /*theDrawList*/)
{
// Assertion for the type of the drawn object
#ifdef _DEBUG
static const Handle(Standard_Type) ThisType =
STANDARD_TYPE(NIS_Line);
if (theObj->IsKind(ThisType) == Standard_False)
{
Standard_ProgramError::Raise("NIS_LineDrawer::Draw: "
"irrelevant object type");
}
#endif
const NIS_Line* pObject =
static_cast <const NIS_Line*> (theObj.operator->());
// Draw line
glBegin(GL_LINES);
glVertex3fv(&pObject->myPoint1[0]);
glVertex3fv(&pObject->myPoint2[0]);
glEnd();
}

View File

@@ -0,0 +1,85 @@
// File: NIS_LineDrawer.h
// Created: 11.05.12
// Author: Natalia Kopnova
// Copyright: LPKF Laser and Electronics AG 2012
#ifndef NIS_LineDrawer_HeaderFile
#define NIS_LineDrawer_HeaderFile
#include <NIS_Drawer.hxx>
class NIS_Line;
/**
* NIS drawer for NIS_Line interactive object type.
* @ingroup aisobject
*/
class NIS_LineDrawer : public NIS_Drawer
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
*/
Standard_EXPORT NIS_LineDrawer (const Quantity_Color& theColor);
/**
* Copy the relevant information from another instance of Drawer.
* raises exception if theOther has incompatible type (test IsKind).
*/
Standard_EXPORT virtual void Assign (const Handle_NIS_Drawer& theOther);
/**
* Called before execution of Draw(), once per group of interactive objects.
*/
Standard_EXPORT virtual void BeforeDraw(const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Called after execution of Draw(), once per group of interactive objects.
*/
Standard_EXPORT virtual void AfterDraw(const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Main function: display the given interactive object in the given view.
*/
Standard_EXPORT virtual void Draw (const Handle_NIS_InteractiveObject&,
const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Matching two instances, for Map interface.
*/
Standard_EXPORT virtual Standard_Boolean
IsEqual (const Handle_NIS_Drawer& theOth)const;
protected:
// ---------- PROTECTED METHODS ----------
private:
// ---------- PRIVATE FIELDS ----------
Standard_ShortReal myLineWidth;
Standard_Integer myType;
Standard_Integer myLineType;
Standard_Boolean myInvertColor;
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_LineDrawer)
friend class NIS_Line;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_LineDrawer, NIS_Drawer)
#endif

View File

@@ -38,6 +38,7 @@ class Handle_NIS_InteractiveContext;
* anIter.Next();
* }
* @endcode
* @ingroup nis_library
*/
class NIS_ObjectsIterator

278
src/NIS/NIS_Point.cxx Normal file
View File

@@ -0,0 +1,278 @@
// File: NIS_Point.cpp
// Created: 12.02.09
// Author: Natalia Kopnova
// Copyright: LPKF Laser and Electronics AG 2008
#include <NIS_Point.hxx>
#include <NIS_PointDrawer.hxx>
#include <NIS_InteractiveContext.hxx>
#include <NIS_Triangulated.hxx>
#include <Precision.hxx>
#include <gp_Ax1.hxx>
IMPLEMENT_STANDARD_HANDLE (NIS_Point, NIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT (NIS_Point, NIS_InteractiveObject)
//=======================================================================
//function : NIS_Point
//purpose : Constructor
//=======================================================================
NIS_Point::NIS_Point
(const gp_XY& thePoint,
const Standard_Real theZ)
: myIs3D (Standard_False)
{
// SetAttributeId(0); // agv: already initialized in the base class
Init(thePoint, theZ);
}
//=======================================================================
//function : NIS_Point
//purpose : Constructor
//=======================================================================
NIS_Point::NIS_Point
(const gp_XYZ& thePoint)
: myIs3D (Standard_True),
myZ (RealLast())
{
// SetAttributeId(0); // agv: already initialized in the base class
Init(thePoint);
}
//=======================================================================
//function : Init
//purpose : Re-initialize the internal structures, re-compute the presentation
//=======================================================================
void NIS_Point::Init(const gp_XY& thePoint,
const Standard_Real theZ)
{
myZ = theZ;
myCoords[0] = static_cast<Standard_ShortReal> (thePoint.X());
myCoords[1] = static_cast<Standard_ShortReal> (thePoint.Y());
myCoords[2] = static_cast<Standard_ShortReal> (myZ);
if (GetDrawer().IsNull() == Standard_False)
{
setDrawerUpdate();
}
setIsUpdateBox(Standard_True);
}
//=======================================================================
//function : Init
//purpose : Re-initialize the internal structures, re-compute the presentation
//=======================================================================
void NIS_Point::Init(const gp_XYZ& thePoint)
{
myCoords[0] = static_cast<Standard_ShortReal> (thePoint.X());
myCoords[1] = static_cast<Standard_ShortReal> (thePoint.Y());
myCoords[2] = static_cast<Standard_ShortReal> (thePoint.Z());
if (GetDrawer().IsNull() == Standard_False)
{
setDrawerUpdate();
}
setIsUpdateBox(Standard_True);
}
//=======================================================================
//function : ~NIS_Point
//purpose : Destructor
//=======================================================================
NIS_Point::~NIS_Point()
{
}
//=======================================================================
//function : DefaultDrawer
//purpose :
//=======================================================================
NIS_Drawer* NIS_Point::DefaultDrawer (NIS_Drawer* theDrawer) const
{
if (theDrawer == 0L)
{
return new NIS_PointDrawer(Quantity_NOC_GREEN);
}
return theDrawer;
}
//=======================================================================
//function : Clone
//purpose :
//=======================================================================
void NIS_Point::Clone
(const Handle_NCollection_BaseAllocator& theAlloc,
Handle_NIS_InteractiveObject& theDest) const
{
Handle(NIS_Point) aNewObj;
if (theDest.IsNull())
{
aNewObj = new NIS_Point;
theDest = aNewObj;
}
else
{
aNewObj = reinterpret_cast<NIS_Point*> (theDest.operator->());
}
NIS_InteractiveObject::Clone(theAlloc, theDest);
aNewObj->myIs3D = myIs3D;
aNewObj->myZ = myZ;
aNewObj->myCoords[0] = myCoords[0];
aNewObj->myCoords[1] = myCoords[1];
aNewObj->myCoords[2] = myCoords[2];
}
//=======================================================================
//function : SetPointSize
//purpose : Set the size of point presentations in pixels.
//=======================================================================
void NIS_Point::SetPointSize (const Standard_Real theSize)
{
const Handle(NIS_PointDrawer) aDrawer =
static_cast<NIS_PointDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
aDrawer->myPointSize = static_cast<Standard_ShortReal>(theSize);
SetDrawer(aDrawer);
}
//=======================================================================
//function : SetMarkerType
//purpose : Set the type of point presentation.
//=======================================================================
void NIS_Point::SetMarkerType (const NIS_MarkerType theType)
{
const Handle(NIS_PointDrawer) aDrawer =
static_cast<NIS_PointDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
aDrawer->myType = static_cast<Standard_Integer>(theType);
SetDrawer(aDrawer);
}
//=======================================================================
//function : SetInvertColor
//purpose : Indicates whether to draw point depending on underlying objects
//=======================================================================
void NIS_Point::SetInvertColor (const Standard_Boolean theInvert)
{
const Handle(NIS_PointDrawer) aDrawer =
static_cast<NIS_PointDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
aDrawer->myInvertColor = static_cast<Standard_Boolean>(theInvert);
SetDrawer(aDrawer);
// // Use "trasparency" layer for drawing (after all objects)
// SetTransparency();
}
//=======================================================================
//function : SetAngle
//purpose :
//=======================================================================
void NIS_Point::SetAngle (const Standard_Real theAngle)
{
const Handle(NIS_PointDrawer) aDrawer =
static_cast<NIS_PointDrawer*>(DefaultDrawer(0L));
aDrawer->Assign(GetDrawer());
Standard_Real anAngle = theAngle;
while (anAngle > M_PI / 2.0)
{
anAngle -= M_PI;
}
while (anAngle < - M_PI / 2.0)
{
anAngle += M_PI;
}
if (std::abs(aDrawer->myAngle - anAngle) > Precision::Angular())
{
aDrawer->myAngle = anAngle;
aDrawer->myIsUpdateAngle = Standard_True;
}
SetDrawer(aDrawer);
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Boolean NIS_Point::Intersect
(const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean /*isFullIn*/) const
{
gp_XYZ aPnt (static_cast<Standard_Real>(myCoords[0]),
static_cast<Standard_Real>(myCoords[1]),
static_cast<Standard_Real>(myCoords[2]));
theTrf.Transforms(aPnt);
return !theBox.IsOut(aPnt);
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Real NIS_Point::Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver) const
{
Standard_Real aResult (RealLast());
// We extend the intersect distance to facilitate selection
const Standard_Real anOver2 = theOver * theOver * 5.;
// check if the point is closed to line
const gp_XYZ& aStart = theAxis.Location().XYZ();
const gp_XYZ& aDir = theAxis.Direction().XYZ();
const gp_XYZ aDelta(static_cast<Standard_Real>(myCoords[0]) - aStart.X(),
static_cast<Standard_Real>(myCoords[1]) - aStart.Y(),
static_cast<Standard_Real>(myCoords[2]) - aStart.Z());
if ((aDelta ^ aDir).SquareModulus() < anOver2)
{
aResult = aDelta * aDir;
}
return aResult;
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Boolean NIS_Point::Intersect
(const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean /*isFullIn*/) const
{
gp_XYZ aPnt (static_cast<Standard_Real>(myCoords[0]),
static_cast<Standard_Real>(myCoords[1]),
static_cast<Standard_Real>(myCoords[2]));
theTrf.Transforms(aPnt);
gp_XY aP2d(aPnt.X(), aPnt.Y());
return NIS_Triangulated::IsIn(thePolygon, aP2d);
}
//=======================================================================
//function : computeBox
//purpose :
//=======================================================================
void NIS_Point::computeBox ()
{
myBox.Clear();
myBox.Add (gp_XYZ(static_cast<Standard_Real>(myCoords[0]),
static_cast<Standard_Real>(myCoords[1]),
static_cast<Standard_Real>(myCoords[2])));
myBox.Enlarge(2.0f); // enlarge a sensetive area
}

240
src/NIS/NIS_Point.hxx Normal file
View File

@@ -0,0 +1,240 @@
// File: NIS_Point.h
// Created: 11.05.12
// Author: Natalia Kopnova
// Copyright: LPKF Laser and Electronics AG 2012
#ifndef NIS_Point_HeaderFile
#define NIS_Point_HeaderFile
#include <NIS_InteractiveObject.hxx>
//! Marker type enumeration.
//! @ingroup aisobject
enum NIS_MarkerType {
NIS_MT_POINT = 0,
NIS_MT_PLUS,
NIS_MT_STAR,
NIS_MT_CROSS,
NIS_MT_CIRCLE,
NIS_MT_FILLED_CIRCLE,
NIS_MT_ARROW_RIGHT,
NIS_MT_ARROW_UP,
NIS_MT_ARROW_LEFT,
NIS_MT_ARROW_DOWN,
NIS_MT_ARROW_UP_RIGHT,
NIS_MT_ARROW_UP_LEFT,
NIS_MT_ARROW_DOWN_LEFT,
NIS_MT_ARROW_DOWN_RIGHT,
NIS_MT_SQUARE,
NIS_MT_TRIANGLE,
NIS_MT_CIRCLE_BOLD,
NIS_MT_CROSS_BOLD,
NIS_MT_ROMB,
NIS_MT_CROSS_CIRCLE,
NIS_MT_LINE
};
/**
* Interactive Object for 2D/3D points
* @ingroup aisobject
*/
class NIS_Point : public NIS_InteractiveObject
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Constructor for 2D point.
*/
Standard_EXPORT NIS_Point (const gp_XY& thePoint,
const Standard_Real theZ);
/**
* Constructor for 3D point.
*/
Standard_EXPORT NIS_Point (const gp_XYZ& thePoint);
/**
* Destructor.
*/
Standard_EXPORT virtual ~NIS_Point ();
/**
* Re-initialize the internal structures, re-compute the presentation
* If only Z is changed, then recompute is much faster.
*/
Standard_EXPORT void Init(const gp_XY& thePoint,
const Standard_Real theZ);
/**
* Re-initialize the internal structures, re-compute the presentation
*/
Standard_EXPORT void Init(const gp_XYZ& thePoint);
/**
* Create a default drawer instance.
*/
Standard_EXPORT virtual NIS_Drawer*
DefaultDrawer (NIS_Drawer*) const;
/**
* Method required by NIS_InteractiveContext.
*/
Standard_EXPORT virtual void Clone (const Handle_NCollection_BaseAllocator&,
Handle_NIS_InteractiveObject&) const;
/**
* Return coordinates of the Point
*/
inline gp_Pnt GetLocation() const
{
return gp_Pnt(myCoords[0], myCoords[1], myCoords[2]);
}
/**
* Set the size of point presentations in pixels.
* @param theSize
* New point size to use for the presentation.
*/
Standard_EXPORT void SetPointSize (const Standard_Real theSize);
/**
* Set the type of point presentations.
* @param theType
* Type of marker to use for the presentation.
*/
Standard_EXPORT void SetMarkerType (const NIS_MarkerType theType);
/**
* Set whether the point color should be inverted depending on
* the color of underlying objects.
* @param theInvert
* True to invert color.
*/
Standard_EXPORT void SetInvertColor (const Standard_Boolean theInvert);
/**
* Set the angle of the bitmap rotation.
* New bitmap will be generated if theAngle is not equal to zero.
* @param theAngle
* The angle of the bitmap rotation.
*/
Standard_EXPORT void SetAngle (const Standard_Real theAngle);
/**
* Intersect the InteractiveObject geometry with an oriented box.
* @param theBox
* 3D box of selection
* @param theTrf
* Position/Orientation of the box.
* @param isFull
* True if full inclusion is required, False - if partial.
* @return
* True if the InteractiveObject geometry intersects the box or is inside it
*/
Standard_EXPORT virtual Standard_Boolean
Intersect (const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean isFull)const;
/**
* Intersect the InteractiveObject geometry with a line/ray.
* @param theAxis
* The line or ray in 3D space.
* @param theOver
* Half-thickness of the selecting line.
* @return
* If the return value is more than 0.1*RealLast() then no intersection is
* detected. Otherwise returns the coordinate of thePnt on the ray. May be
* negative.
*/
Standard_EXPORT virtual Standard_Real
Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver)const;
/**
* Intersect the InteractiveObject geometry with a selection polygon.
* @param thePolygon
* the list of vertices of a free-form closed polygon without
* self-intersections. The last point should not coincide with the first
* point of the list. Any two neighbor points should not be confused.
* @param theTrf
* Position/Orientation of the polygon.
* @param isFull
* True if full inclusion is required, False - if partial.
* @return
* True if the InteractiveObject geometry intersects the polygon or is
* inside it
*/
Standard_EXPORT virtual Standard_Boolean Intersect
(const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean isFull) const;
/**
* Store an integer value as attribute of the Object.
*/
inline void SetAttributeId (const Standard_Integer theId)
{
SetAttribute (reinterpret_cast <void*> (theId));
}
/**
* Returns the attribute value previously stored using SetAttributeId.
* Value 0 signifies that the AttributeId has not been set (as this is
* the constructor default value).
*/
inline Standard_Integer GetAttributeId () const
{
return reinterpret_cast <Standard_Integer> (GetAttribute());
}
/**
* Query if the Point is a 3D object.
*/
inline Standard_Boolean Is3D () const
{
return myIs3D;
}
protected:
//! Empty constructor for method Clone()
inline NIS_Point()
{}
/**
* Create a 3D bounding box of the object.
*/
Standard_EXPORT virtual void computeBox ();
private:
// ---------- PRIVATE METHODS ----------
NIS_Point (const NIS_Point& theOther);
NIS_Point& operator= (const NIS_Point& theOther);
protected:
// ---------- PRIVATE FIELDS ----------
Standard_Boolean myIs3D;
Standard_Real myZ;
/**
* Array of coords
*/
Standard_ShortReal myCoords[3];
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_Point)
friend class NIS_PointDrawer;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_Point, NIS_InteractiveObject)
#endif

1621
src/NIS/NIS_PointDrawer.cxx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
// File: NIS_PointDrawer.h
// Created: 11.05.12
// Author: Natalia Kopnova
// Copyright: LPKF Laser and Electronics AG 2012
#ifndef NIS_PointDrawer_HeaderFile
#define NIS_PointDrawer_HeaderFile
#include <NIS_Drawer.hxx>
class NIS_Point;
/**
* NIS drawer for AISObject_Point interactive object type.
* @ingroup aisobject
*/
class NIS_PointDrawer : public NIS_Drawer
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
*/
Standard_EXPORT NIS_PointDrawer (const Quantity_Color& theColor);
/**
* Destructor.
*/
Standard_EXPORT virtual ~NIS_PointDrawer ();
/**
* Copy the relevant information from another instance of Drawer.
* raises exception if theOther has incompatible type (test IsKind).
*/
Standard_EXPORT virtual void Assign (const Handle_NIS_Drawer& theOther);
/**
* Called before execution of Draw(), once per group of interactive objects.
*/
Standard_EXPORT virtual void BeforeDraw(const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Called after execution of Draw(), once per group of interactive objects.
*/
Standard_EXPORT virtual void AfterDraw(const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Main function: display the given interactive object in the given view.
*/
Standard_EXPORT virtual void Draw (const Handle_NIS_InteractiveObject&,
const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Matching two instances, for Map interface.
*/
Standard_EXPORT virtual Standard_Boolean
IsEqual (const Handle_NIS_Drawer& theOth)const;
protected:
// ---------- PROTECTED METHODS ----------
/**
* Draw single point represented as texture at input position
*/
Standard_EXPORT virtual void DrawPoint (const Standard_ShortReal* thePosition);
private:
// ---------- PRIVATE FIELDS ----------
Standard_ShortReal myPointSize;
Standard_Integer myType;
Standard_Integer mySizeIndex;
Standard_Boolean myInvertColor;
Standard_Boolean myIsWhite;
Standard_Boolean myIsUpdateAngle;
Standard_Real myAngle;
unsigned char* myRotatedRaster;
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_PointDrawer)
friend class NIS_Point;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_PointDrawer, NIS_Drawer)
#endif

View File

@@ -0,0 +1,407 @@
// File: NIS_PolygonSelector.cxx
// Created: 26.10.11 21:26
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2011
#include <NIS_PolygonSelector.hxx>
#include <NIS_InteractiveContext.hxx>
#include <NIS_View.hxx>
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
/**
* Drawer class for PolygonSelector.
*/
class NIS_PolygonSelectorDrawer : public NIS_Drawer
{
public:
/**
* Display the given interactive object in the given view.
*/
virtual void Draw (const Handle_NIS_InteractiveObject&,
const DrawType theType,
const NIS_DrawList& theDrawList);
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_PolygonSelectorDrawer)
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_PolygonSelectorDrawer, NIS_Drawer)
IMPLEMENT_STANDARD_HANDLE (NIS_PolygonSelector, NIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT (NIS_PolygonSelector, NIS_InteractiveObject)
IMPLEMENT_STANDARD_HANDLE (NIS_PolygonSelectorDrawer, NIS_Drawer)
IMPLEMENT_STANDARD_RTTIEXT (NIS_PolygonSelectorDrawer, NIS_Drawer)
//=======================================================================
//function : ~NIS_PolygonSelector
//purpose : Destructor
//=======================================================================
NIS_PolygonSelector::~NIS_PolygonSelector ()
{
}
//=======================================================================
//function : DefaultDrawer
//purpose :
//=======================================================================
NIS_Drawer * NIS_PolygonSelector::DefaultDrawer(NIS_Drawer * theDrawer) const
{
NIS_PolygonSelectorDrawer * aDrawer =
theDrawer ? static_cast<NIS_PolygonSelectorDrawer *>(theDrawer)
: new NIS_PolygonSelectorDrawer();
aDrawer->SetCompiled(Standard_False);
return aDrawer;
}
//=======================================================================
//function : Clone
//purpose :
//=======================================================================
void NIS_PolygonSelector::Clone
(const Handle_NCollection_BaseAllocator& theAlloc,
Handle_NIS_InteractiveObject& theDest) const
{
Handle(NIS_PolygonSelector) aNewObj;
if (theDest.IsNull())
{
aNewObj = new NIS_PolygonSelector(myIsRectangle);
theDest = aNewObj;
}
else
{
aNewObj = reinterpret_cast<NIS_PolygonSelector*> (theDest.operator->());
}
NIS_InteractiveObject::Clone(theAlloc, theDest);
aNewObj->myView = myView;
aNewObj->myIsRectangle = myIsRectangle;
aNewObj->myIsLoop = myIsLoop;
if (myPoints.Extent() > 0)
{
aNewObj->myPoints = myPoints;
aNewObj->myVertexes =
new NCollection_Array1<Standard_ShortReal>(*myVertexes.operator->());
}
}
//=======================================================================
//function : Intersect
//purpose : Not used
//=======================================================================
Standard_Real NIS_PolygonSelector::Intersect (const gp_Ax1&,
const Standard_Real) const
{
return RealLast();
}
//=======================================================================
//function : computeBox
//purpose : Not used
//=======================================================================
void NIS_PolygonSelector::computeBox ()
{
}
//=======================================================================
//function : AddPoint
//purpose : Add a point to polygon
//=======================================================================
void NIS_PolygonSelector::AddPoint (const Standard_Integer theX,
const Standard_Integer theY)
{
// add the point to the list
gp_XYZ aPnt = convertPoint( theX, theY );
myPoints.Prepend( aPnt );
updateVertexes();
}
//=======================================================================
//function : MovePoint
//purpose : Change the location of the last added point.
//=======================================================================
void NIS_PolygonSelector::MovePoint (const Standard_Integer theX,
const Standard_Integer theY)
{
if (myPoints.IsEmpty())
AddPoint( theX, theY );
else if (myIsRectangle && myPoints.Extent() == 1)
AddPoint( theX, theY );
else {
gp_XYZ aMovedPnt = convertPoint( theX, theY );
gp_XYZ& aPnt = const_cast<gp_XYZ&>( myPoints.First() );
aPnt.SetX( aMovedPnt.X() );
aPnt.SetY( aMovedPnt.Y() );
aPnt.SetZ( aMovedPnt.Z() );
updateVertexes();
}
}
//=======================================================================
//function : RemovePoint
//purpose : Remove the last added point
//=======================================================================
void NIS_PolygonSelector::RemovePoint ()
{
if (NPoints() > 0)
{
myPoints.RemoveFirst();
updateVertexes();
}
}
//=======================================================================
//function : Draw
//purpose :
//=======================================================================
void NIS_PolygonSelectorDrawer::Draw(const Handle_NIS_InteractiveObject& theObj,
const DrawType theType,
const NIS_DrawList& theDrawList)
{
if (theObj.IsNull() == Standard_False &&
theObj->IsKind(STANDARD_TYPE(NIS_PolygonSelector)))
{
const NIS_PolygonSelector * pObj =
static_cast<const NIS_PolygonSelector *>(theObj.operator->());
Standard_Integer nPnts = pObj->NPoints();
if (pObj->myView.IsNull() == Standard_False &&
theDrawList.GetView().IsNull() == Standard_False)
{
if (pObj->myView != theDrawList.GetView())
nPnts = 0;
}
if (nPnts > 0)
{
GLenum aMode;
glEnableClientState(GL_VERTEX_ARRAY);
const Standard_ShortReal* aVertexes =
&pObj->myVertexes->Value( pObj->myVertexes->Lower() );
glVertexPointer(3, GL_FLOAT, 0, aVertexes );
if (nPnts == 1)
{
glEnable(GL_POINT_SMOOTH);
glPointSize(3.f);
aMode = GL_POINTS;
}
else
{
glDisable(GL_LINE_SMOOTH);
// glEnable(GL_LINE_STIPPLE);
// glLineStipple(1, 0x3333);
glLineWidth(0.5f);
if (nPnts == 2)
{
aMode = GL_LINES;
}
else if (!pObj->myIsRectangle && !pObj->myIsLoop)
{
aMode = GL_LINE_STRIP;
}
else
{
aMode = GL_LINE_LOOP;
}
}
glDisable (GL_LIGHTING);
Quantity_Parameter R1, R2, R3;
GetColor(theType).Values(R1, R2, R3, Quantity_TOC_RGB);
glColor3d (R1, R2, R3);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
glDrawArrays(aMode, 0, nPnts);
glDisable(GL_BLEND);
// glDisable(GL_LINE_STIPPLE);
glDisableClientState(GL_VERTEX_ARRAY);
glEnable (GL_LIGHTING);
}
}
}
//=======================================================================
//function : convertPoint
//purpose :
//=======================================================================
gp_XYZ NIS_PolygonSelector::convertPoint ( Standard_Integer theX,
Standard_Integer theY )
{
Standard_Real aPickPnt[3];
const Handle(NIS_View) aView = getView();
if (aView.IsNull() == Standard_False)
{
aView->Convert (static_cast<Standard_Integer>(theX),
static_cast<Standard_Integer>(theY),
aPickPnt[0], aPickPnt[1], aPickPnt[2]);
}
return gp_XYZ( aPickPnt[0], aPickPnt[1], aPickPnt[2] );
}
//=======================================================================
//function : getView
//purpose :
//=======================================================================
const Handle_NIS_View& NIS_PolygonSelector::getView () const
{
const Handle(NIS_Drawer)& aDrawer = GetDrawer();
if (aDrawer.IsNull() == Standard_False) {
const NIS_InteractiveContext * aCtx = aDrawer->GetContext();
if (aCtx != NULL) {
NCollection_List<Handle_NIS_View>::Iterator aViews = aCtx->GetViews();
if (aViews.More())
return aViews.Value();
}
}
static const Handle(NIS_View) aNull;
return aNull;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void NIS_PolygonSelector::Perform (const Standard_Boolean isModifierUsed,
const Standard_Boolean isFullyIncluded,
const Standard_Boolean isRedraw) const
{
// Find the View
Handle(NIS_View) aView = myView;
if (myView.IsNull() && GetDrawer().IsNull() == Standard_False)
{
const NIS_InteractiveContext * aCtx = GetDrawer()->GetContext();
if (aCtx != 0L)
{
NCollection_List<Handle_NIS_View>::Iterator anIterV = aCtx->GetViews();
if (anIterV.More())
aView = anIterV.Value();
}
}
if (aView.IsNull() == Standard_False)
{
NCollection_List<gp_XY> aSelectionPnts = GetPolygon();
if (myIsRectangle == Standard_False)
{
// Polygon selection
aView->Select( aSelectionPnts, isModifierUsed, isFullyIncluded, isRedraw );
}
else
{
// Rectangle selection
Standard_Integer aV[4] = {
static_cast<Standard_Integer>( aSelectionPnts.First().X() + 0.1 ),
static_cast<Standard_Integer>( aSelectionPnts.First().Y() + 0.1 ),
static_cast<Standard_Integer>( aSelectionPnts.Last().X() + 0.1 ),
static_cast<Standard_Integer>( aSelectionPnts.Last().Y() + 0.1 )
};
if (aV[0] > aV[2]) {
const Standard_Integer aTmp = aV[0];
aV[0] = aV[2];
aV[2] = aTmp;
}
if (aV[1] > aV[3]) {
const Standard_Integer aTmp = aV[1];
aV[1] = aV[3];
aV[3] = aTmp;
}
aView->Select(aV[0], aV[1], aV[2], aV[3], isModifierUsed, isFullyIncluded, isRedraw);
}
}
}
//=======================================================================
//function : GetPolygon
//purpose :
//=======================================================================
NCollection_List<gp_XY> NIS_PolygonSelector::GetPolygon() const
{
NCollection_List<gp_XY> aScreenCoords;
const Handle_NIS_View& aView = getView();
if (aView.IsNull() == Standard_False)
{
NCollection_List<gp_XYZ>::Iterator anIt(myPoints);
Standard_Integer aScreenX, aScreenY;
for (; anIt.More(); anIt.Next())
{
gp_XYZ aViewPnt = anIt.Value();
aView->Convert(aViewPnt.X(), aViewPnt.Y(), aViewPnt.Z(),
aScreenX, aScreenY);
aScreenCoords.Append( gp_XY(aScreenX, aScreenY));
}
}
return aScreenCoords;
}
//=======================================================================
//function : updateVertexes
//purpose :
//=======================================================================
void NIS_PolygonSelector::updateVertexes()
{
myVertexes = new NCollection_Array1<Standard_ShortReal>(0, NPoints() * 3);
if (myIsRectangle)
{
gp_XYZ aPnt1 = myPoints.Last();
gp_XYZ aPnt2 = myPoints.First();
Quantity_Parameter anUpX, anUpY, anUpZ;
Handle(NIS_View) aView = getView();
aView->Up( anUpX, anUpY, anUpZ );
gp_XYZ anUp( anUpX, anUpY, anUpZ );
gp_XYZ aPnt3 = aPnt1 - anUp * (anUp * (aPnt1 - aPnt2));
gp_XYZ aPnt4 = aPnt2 + anUp * (anUp * (aPnt1 - aPnt2));
myVertexes->ChangeValue(0) = static_cast<Standard_ShortReal>(aPnt1.X());
myVertexes->ChangeValue(1) = static_cast<Standard_ShortReal>(aPnt1.Y());
myVertexes->ChangeValue(2) = static_cast<Standard_ShortReal>(aPnt1.Z());
myVertexes->ChangeValue(3) = static_cast<Standard_ShortReal>(aPnt3.X());
myVertexes->ChangeValue(4) = static_cast<Standard_ShortReal>(aPnt3.Y());
myVertexes->ChangeValue(5) = static_cast<Standard_ShortReal>(aPnt3.Z());
myVertexes->ChangeValue(6) = static_cast<Standard_ShortReal>(aPnt2.X());
myVertexes->ChangeValue(7) = static_cast<Standard_ShortReal>(aPnt2.Y());
myVertexes->ChangeValue(8) = static_cast<Standard_ShortReal>(aPnt2.Z());
myVertexes->ChangeValue(9) = static_cast<Standard_ShortReal>(aPnt4.X());
myVertexes->ChangeValue(10) = static_cast<Standard_ShortReal>(aPnt4.Y());
myVertexes->ChangeValue(11) = static_cast<Standard_ShortReal>(aPnt4.Z());
}
else
{
Standard_Integer i = 0;
NCollection_List<gp_XYZ>::Iterator anIter( myPoints );
for (; anIter.More(); anIter.Next())
{
myVertexes->ChangeValue(i++) =
static_cast<Standard_ShortReal>( anIter.Value().X() );
myVertexes->ChangeValue(i++) =
static_cast<Standard_ShortReal>( anIter.Value().Y() );
myVertexes->ChangeValue(i++) =
static_cast<Standard_ShortReal>( anIter.Value().Z() );
}
}
setDrawerUpdate();
}

View File

@@ -0,0 +1,141 @@
// File: NIS_PolygonSelector.hxx
// Created: 26.10.11 21:17
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2011
#ifndef NIS_PolygonSelector_HeaderFile
#define NIS_PolygonSelector_HeaderFile
#include <NIS_InteractiveObject.hxx>
#include <NCollection_List.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_Handle.hxx>
class NIS_PolygonSelectorDrawer;
typedef NCollection_Array1<Standard_ShortReal> ShortRealArray;
typedef NCollection_Handle<ShortRealArray> Handle(ShortRealArray);
/**
* Data structure and presentation of a polygon or rectangle shown above all
* other objects in 3D viewer. Can be used for interactive seclection.
* @ingroup nis_library
*/
class NIS_PolygonSelector : public NIS_InteractiveObject
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
* @param isRectangle
* If True then a rectangle is drawn by 2 points, if False - a polygon on
* a set of points.
* @param isLoop
* This parameter makes sence only for polygon mode.
* If 'false' the line between the first and the last points is nopt displayed.
* otherwise these points are connected.
* @param theView
* If defined then the polygon/rectangle will be shown only in tthis view.
* If undefined then all views will contain the presentation.
*/
inline NIS_PolygonSelector (const Standard_Boolean isRectangle,
const Standard_Boolean isLoop = 1,
const Handle_NIS_View& theView = 0L)
: myView (theView),
myIsRectangle (isRectangle),
myIsLoop (isLoop) {}
/**
* Query the number of polygon vertices.
*/
inline Standard_Integer NPoints () const
{ return myIsRectangle ? 4 : myPoints.Extent(); }
/**
* Query the drawing mode.
*/
inline Standard_Boolean IsRectangle () const
{ return myIsRectangle; }
Standard_EXPORT ~NIS_PolygonSelector ();
Standard_EXPORT virtual NIS_Drawer *
DefaultDrawer (NIS_Drawer * theDrv) const;
/**
* Create a copy of theObject except its ID.
*/
Standard_EXPORT virtual void
Clone (const Handle_NCollection_BaseAllocator& theAll,
Handle_NIS_InteractiveObject& theDest) const;
Standard_EXPORT virtual Standard_Real
Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver)const;
Standard_EXPORT virtual void
computeBox ();
/**
* Add a point to polygon.
*/
Standard_EXPORT void AddPoint (const Standard_Integer theX,
const Standard_Integer theY);
/**
* Change the location of the last added point.
*/
Standard_EXPORT void MovePoint (const Standard_Integer theX,
const Standard_Integer theY);
/**
* Remove the last added point.
*/
Standard_EXPORT void RemovePoint ();
/**
* Perform the selection in the current view (myView). If myView.IsNull() then
* the selection is performed in the first view attached to the Interactive
* context. The selection is only performed for NIS_InteractiveObjects; for
* AIS_InteractiveObject type use additional selection call.
* @param isModifierUsed
* The modifier buttons state (e.g., when Shift is pressed).
* @param isFulInc
* Tells if only those objects are selected that are fully inside the
* selection area.
* @param isRedraw
* True to redraw view automatically (default value).
*/
Standard_EXPORT void Perform (const Standard_Boolean isModifierUsed,
const Standard_Boolean isFulInc,
const Standard_Boolean isRedraw = Standard_True) const;
Standard_EXPORT NCollection_List<gp_XY> GetPolygon () const;
private:
const Handle_NIS_View& getView () const;
gp_XYZ convertPoint (const Standard_Integer theX,
const Standard_Integer theY);
void updateVertexes ();
// ---------- PRIVATE FIELDS ----------
Handle_NIS_View myView;
NCollection_List<gp_XYZ> myPoints;
Handle(ShortRealArray) myVertexes;
Standard_Boolean myIsRectangle;
Standard_Boolean myIsLoop;
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_PolygonSelector)
friend class NIS_PolygonSelectorDrawer;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_PolygonSelector, NIS_InteractiveObject)
#endif

View File

@@ -18,6 +18,23 @@
IMPLEMENT_STANDARD_HANDLE (NIS_SelectFilter, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT (NIS_SelectFilter, Standard_Transient)
//=======================================================================
//function : IsOk
//purpose :
//=======================================================================
Standard_Boolean NIS_SelectFilter::IsOk
(const NIS_InteractiveObject * theObject,
const gp_Ax1&,
const Standard_Real,
const Event theEvent) const
{
Standard_Boolean aResult(Standard_False);
if (theEvent == Indefinite || (theEvent & myEventFlags) != 0)
aResult = IsOk(theObject, theEvent);
return aResult;
}
//=======================================================================
//function : ActsOn
//purpose :
@@ -28,4 +45,3 @@ Standard_Boolean NIS_SelectFilter::ActsOn (const Handle_Standard_Type&) const
return Standard_True;
}

View File

@@ -21,6 +21,7 @@
class NIS_InteractiveObject;
class Handle_Standard_Type;
class gp_Ax1;
/**
* Interface for selection filters. It can be used in NIS_InteractiveContext
@@ -29,18 +30,32 @@ class Handle_Standard_Type;
* you need more than one filter instance to work together, create a composite
* NIS_SelectFilter specialization that would hold a list of simpler Filter
* instances.
* @ingroup nis_library
*/
class NIS_SelectFilter : public Standard_Transient
{
public:
// ---------- PUBLIC METHODS ----------
//! binary flags (1,2,4,8,...) describing the events for which it responds
enum Event {
Indefinite = 0,
Pick = 1,
DynHilight = 2,
Picked = 4,
DynHilighted = 8
};
/**
* Empty constructor.
*/
inline NIS_SelectFilter () {}
inline NIS_SelectFilter () : myEventFlags (Pick | DynHilight) {}
/**
* Set the combination of events as bit flags defined in enum Event.
*/
inline void SetEventFlags (const unsigned int theFlags)
{ myEventFlags = theFlags; }
/**
* Indicate that the given NIS_InteractiveObject passes the Filter.
@@ -48,7 +63,32 @@ class NIS_SelectFilter : public Standard_Transient
* True - theObject is kept in the Selection, False - excluded from it.
*/
virtual Standard_Boolean
IsOk (const NIS_InteractiveObject * theObject) const = 0;
IsOk (const NIS_InteractiveObject * theObject,
const Event theEvent = Indefinite) const = 0;
/**
* Indicate that the given NIS_InteractiveObject passes the Filter.
* This method is called during a selection by mouse click. If it returns
* True then the normal hilighting is performed. Otherwise the object
* is skipped from hilighted selection but this method may perform some
* special actions, if redefined. the default implementation just calls
* the previous method IsOk.
* @param theObject
* Tested object.
* @param theAxis
* Selection ray
* @param theOver
* Thickness of the selecting ray
* @param theEvent
* Event type that invokes this method.
* @return
* True - theObject is kept in the Selection, False - excluded from it.
*/
Standard_EXPORT virtual Standard_Boolean
IsOk (const NIS_InteractiveObject * theObject,
const gp_Ax1& theAxis,
const Standard_Real theOver,
const Event theEvent = Indefinite) const;
/**
* Check if the type of InteractiveObject is allowed for selection.
@@ -64,8 +104,7 @@ class NIS_SelectFilter : public Standard_Transient
protected:
// ---------- PROTECTED METHODS ----------
unsigned int myEventFlags;
public:
// Declaration of CASCADE RTTI

View File

@@ -31,6 +31,8 @@
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
@@ -57,15 +59,16 @@ inline Standard_Boolean IsEqual(const Handle_Poly_Triangulation& theT0,
//=======================================================================
NIS_Surface::NIS_Surface(const Handle_NCollection_BaseAllocator& theAlloc)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypTriangles (NULL),
mypEdges (NULL),
myNNodes (0),
myNTriangles (0),
myNEdges (0),
myIsWireframe(0)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypTriangles (NULL),
myNNodes (0),
myNTriangles (0),
myIsWireframe (Standard_False),
myHilightIsWireframe(Standard_False),
myIsShowFreeBoundary(Standard_False),
myIsShowEdges (Standard_True)
{
if (myAlloc.IsNull())
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
@@ -78,14 +81,15 @@ NIS_Surface::NIS_Surface(const Handle_NCollection_BaseAllocator& theAlloc)
NIS_Surface::NIS_Surface (const Handle(Poly_Triangulation)& theTri,
const Handle_NCollection_BaseAllocator& theAlloc)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypEdges (NULL),
myNNodes (0),
myNTriangles (0),
myNEdges (0),
myIsWireframe(0)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
myNNodes (0),
myNTriangles (0),
myIsWireframe (Standard_False),
myHilightIsWireframe(Standard_False),
myIsShowFreeBoundary(Standard_False),
myIsShowEdges (Standard_True)
{
if (myAlloc.IsNull())
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
@@ -147,18 +151,20 @@ NIS_Surface::NIS_Surface (const Handle(Poly_Triangulation)& theTri,
//purpose : Constructor
//=======================================================================
NIS_Surface::NIS_Surface (const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
NIS_Surface::NIS_Surface (const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Boolean theIsFreeBoundary,
const Handle_NCollection_BaseAllocator& theAlloc)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypTriangles (NULL),
mypEdges (NULL),
myNNodes (0),
myNTriangles (0),
myNEdges (0),
myIsWireframe (0)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypTriangles (NULL),
myNNodes (0),
myNTriangles (0),
myIsWireframe (Standard_False),
myHilightIsWireframe(Standard_False),
myIsShowFreeBoundary(theIsFreeBoundary),
myIsShowEdges (Standard_True)
{
if (myAlloc.IsNull())
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
@@ -174,35 +180,86 @@ void NIS_Surface::Init (const TopoDS_Shape& theShape,
const Standard_Real theDeflection)
{
TopLoc_Location aLoc, aLocSurf;
Clear();
//Upon initialization by TopoDS_Shape the check of triangulation is performed.
//If at least one face has no triangulation but has a surface then the whole
// shape is triangulated using BRepMesh.
//The whole shape triangulation is required to respect boundary connection
Standard_Boolean hasTri = Standard_True;
TopExp_Explorer eexp;
TopExp_Explorer fexp (theShape, TopAbs_FACE);
for (; fexp.More() && hasTri; fexp.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
const Handle(Poly_Triangulation)& aTriangulation
= BRep_Tool::Triangulation (aFace, aLoc);
const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(aFace, aLoc);
if ((aTriangulation.IsNull() && Standard_False == aSurface.IsNull()) ||
(Standard_False == aTriangulation.IsNull() &&
theDeflection < aTriangulation->Deflection() ))
{
hasTri = Standard_False;
break;
}
for (eexp.Init(aFace, TopAbs_EDGE); eexp.More(); eexp.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
const Handle(Poly_PolygonOnTriangulation)& aPolygon =
BRep_Tool::PolygonOnTriangulation(anEdge, aTriangulation, aLoc);
if (aPolygon.IsNull())
{
hasTri = Standard_False;
break;
}
}
}
if( hasTri == Standard_False )
{
const Standard_Real anAngularDeflection = 20.0 * M_PI / 180.0;
BRepMesh_IncrementalMesh aMeshTool(theShape, theDeflection,
Standard_False, anAngularDeflection);
}
// Count the nodes and triangles in faces
NCollection_Map<Handle_Poly_Triangulation> mapTri;
TopExp_Explorer fexp (theShape, TopAbs_FACE);
for (; fexp.More(); fexp.Next())
for (fexp.Init(theShape, TopAbs_FACE); fexp.More(); fexp.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
const Handle(Poly_Triangulation)& aTriangulation
= BRep_Tool::Triangulation (aFace, aLoc);
if (aTriangulation.IsNull())
BRepMesh_IncrementalMesh aMeshTool(aFace, theDeflection);
if (aTriangulation.IsNull() == Standard_False)
{
myNNodes += aTriangulation->NbNodes();
myNTriangles += aTriangulation->NbTriangles();
mapTri.Add(aTriangulation);
}
}
// Create map of edges, to build wireframe for all edges.
TopTools_MapOfShape mapEdges;
TopExp_Explorer eexp (theShape, TopAbs_EDGE);
for (; eexp.More(); eexp.Next())
TopTools_DataMapOfShapeInteger mapEdges;
for (eexp.Init(theShape, TopAbs_EDGE); eexp.More(); eexp.Next())
{
const TopoDS_Shape& anEdge = eexp.Current();
mapEdges.Add(anEdge);
if (mapEdges.IsBound(anEdge))
mapEdges.ChangeFind(anEdge) += 1;
else
mapEdges.Bind(anEdge, 1);
}
Standard_Integer nbFreeEdges = 0, nbEdges = 0;
TopTools_DataMapIteratorOfDataMapOfShapeInteger anEIt(mapEdges);
for (; anEIt.More(); anEIt.Next())
{
const Standard_Integer nb = anEIt.Value();
if (nb > 1)
nbEdges += 1;
else
nbFreeEdges += 1;
}
// Allocate arrays of entities
@@ -213,13 +270,12 @@ void NIS_Surface::Init (const TopoDS_Shape& theShape,
(myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
mypTriangles = static_cast<Standard_Integer *>
(myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
mypEdges = static_cast<Standard_Integer **>
(myAlloc->Allocate(sizeof(Standard_Integer *) * mapEdges.Extent()));
myNEdges = 0;
myEdges.InitArray (2, nbEdges, myAlloc.operator->());
myFreeEdges.InitArray (2, nbFreeEdges, myAlloc.operator->());
// The second loop: copy all nodes and triangles face-by-face
const Standard_Real eps2 = Precision::SquareConfusion();
Standard_Integer nNodes (0), nTriangles (0);
Standard_Integer nNodes (0), nTriangles (0), nEdges (0), nFEdges (0);
for (fexp.ReInit(); fexp.More(); fexp.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
@@ -317,18 +373,21 @@ void NIS_Surface::Init (const TopoDS_Shape& theShape,
// Store all edge polygons on the current face.
for (eexp.Init(aFace, TopAbs_EDGE); eexp.More(); eexp.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
if (mapEdges.Remove(anEdge)) {
const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
if (mapEdges.IsBound(anEdge)) {
Standard_Integer nbE = mapEdges.Find(anEdge);
mapEdges.UnBind(anEdge);
const Handle(Poly_PolygonOnTriangulation)& aPolygon =
BRep_Tool::PolygonOnTriangulation(anEdge, aTriangulation, aLoc);
if (aPolygon.IsNull() == Standard_False) {
const TColStd_Array1OfInteger& arrNode = aPolygon->Nodes();
// Allocate memory to store the current polygon indices.
Standard_Integer aLen = arrNode.Length();
Standard_Integer * pEdge = static_cast<Standard_Integer *>
(myAlloc->Allocate(sizeof(Standard_Integer) * (aLen + 1)));
int * pEdge = static_cast<int *>
(myAlloc->Allocate(sizeof(int) * (aLen)));
const gp_Pnt* pLast = &tabNode(arrNode(arrNode.Lower()));
pEdge[1] = arrNode(arrNode.Lower()) + nNodes1;
pEdge[0] = arrNode(arrNode.Lower()) + nNodes1;
Standard_Integer iPNode(arrNode.Lower() + 1), iENode(1);
for (; iPNode <= arrNode.Upper(); iPNode++)
{
@@ -338,27 +397,33 @@ void NIS_Surface::Init (const TopoDS_Shape& theShape,
aLen--;
} else {
pLast = &tabNode(aN);
pEdge[++iENode] = aN + nNodes1;
pEdge[iENode++] = aN + nNodes1;
}
}
// Do not save very short polygons
if (aLen > 1) {
pEdge[0] = aLen;
mypEdges[myNEdges++] = pEdge;
if (nbE > 1)
myEdges.SetArray(nEdges++, aLen, pEdge, myAlloc.operator->());
else
myFreeEdges.SetArray(nFEdges++, aLen, pEdge,
myAlloc.operator->());
}
myAlloc->Free(pEdge);
}
}
}
nNodes += tabNode.Length();
}
}
myEdges.SetRealNumbersOfArrays(nEdges);
myFreeEdges.SetRealNumbersOfArrays(nFEdges);
myNTriangles = nTriangles;
}
if (GetDrawer().IsNull() == Standard_False)
{
setDrawerUpdate();
}
setIsUpdateBox(Standard_True);
setIsUpdateBox(Standard_True);
}
//=======================================================================
@@ -387,13 +452,10 @@ void NIS_Surface::Clear ()
myNTriangles = 0;
myAlloc->Free(mypTriangles);
}
if (mypEdges) {
for (Standard_Integer i = 0; i < myNEdges; i++) {
myAlloc->Free(mypEdges[i]);
}
myNEdges = 0;
myAlloc->Free(mypEdges);
}
myEdges.Clear(myAlloc.operator->());
myFreeEdges.Clear(myAlloc.operator->());
if (GetDrawer().IsNull() == Standard_False) {
GetDrawer()->SetUpdated(NIS_Drawer::Draw_Normal,
NIS_Drawer::Draw_Top,
@@ -418,22 +480,6 @@ NIS_Drawer * NIS_Surface::DefaultDrawer (NIS_Drawer * theDrawer) const
return aDrawer;
}
//=======================================================================
//function : SetColor
//purpose : Set the normal color for presentation.
//=======================================================================
void NIS_Surface::SetColor (const Quantity_Color& theColor)
{
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myColor[NIS_Drawer::Draw_Normal] = theColor;
aDrawer->myColor[NIS_Drawer::Draw_Top] = theColor;
aDrawer->myColor[NIS_Drawer::Draw_Transparent] = theColor;
SetDrawer (aDrawer);
}
//=======================================================================
//function : SetBackColor
//purpose : Set the normal color for presentation of back side of triangles.
@@ -448,6 +494,20 @@ void NIS_Surface::SetBackColor (const Quantity_Color& theColor)
SetDrawer (aDrawer);
}
//=======================================================================
//function : SetSpecularity
//purpose :
//=======================================================================
void NIS_Surface::SetSpecularity (const Standard_Real theValue)
{
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->SetSpecularity(theValue);
SetDrawer (aDrawer);
}
//=======================================================================
//function : SetPolygonOffset
//purpose :
@@ -462,6 +522,21 @@ void NIS_Surface::SetPolygonOffset (const Standard_Real theValue)
SetDrawer (aDrawer);
}
//=======================================================================
//function : SetTransformation
//purpose :
//=======================================================================
void NIS_Surface::SetTransformation (const gp_Trsf& theTrsf)
{
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->SetTransformation(theTrsf);
SetDrawer (aDrawer);
setIsUpdateBox(Standard_True);
}
//=======================================================================
//function : SetDisplayMode
//purpose : Set the display mode: Shading or Wireframe.
@@ -473,20 +548,37 @@ void NIS_Surface::SetDisplayMode (const NIS_Surface::DisplayMode theMode)
if (myIsWireframe) {
if (theMode != Wireframe) {
myIsWireframe = Standard_False;
myIsShowEdges = (theMode != PureShading);
isUpdate = Standard_True;
}
} else {
if (theMode == Wireframe) {
myIsWireframe = Standard_True;
myIsShowEdges = Standard_True;
isUpdate = Standard_True;
}
else {
if (myIsShowEdges) {
if (theMode == PureShading) {
myIsShowEdges = Standard_False;
isUpdate = Standard_True;
}
}
else {
if (theMode != PureShading) {
myIsShowEdges = Standard_True;
isUpdate = Standard_True;
}
}
}
}
if (isUpdate && !GetDrawer().IsNull()) {
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myIsWireframe = myIsWireframe;
SetDrawer(aDrawer);
aDrawer->myIsShowEdges = myIsShowEdges;
SetDrawer(aDrawer);
}
}
@@ -497,7 +589,86 @@ void NIS_Surface::SetDisplayMode (const NIS_Surface::DisplayMode theMode)
NIS_Surface::DisplayMode NIS_Surface::GetDisplayMode () const
{
return myIsWireframe ? Wireframe : Shading;
return myIsWireframe ? Wireframe : (myIsShowEdges ? Shading : PureShading);
}
//=======================================================================
//function : SetHilightDisplayMode
//purpose : Set the hilight display mode: Shading or Wireframe.
//=======================================================================
void NIS_Surface::SetHilightDisplayMode(const NIS_Surface::DisplayMode theMode)
{
Standard_Boolean isUpdate = Standard_False;
if (myIsWireframe == Standard_True)
{
if (myHilightIsWireframe)
{
myHilightIsWireframe = Standard_False;
isUpdate = Standard_True;
}
}
else
{
if (myHilightIsWireframe) {
if (theMode != Wireframe) {
myHilightIsWireframe = Standard_False;
isUpdate = Standard_True;
}
}
else {
if (theMode == Wireframe) {
myHilightIsWireframe = Standard_True;
isUpdate = Standard_True;
}
}
}
if (isUpdate) {
const Handle(NIS_Drawer)& aCurrDrawer = GetDrawer();
if (aCurrDrawer.IsNull() == Standard_False) {
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myHilightIsWireframe = myHilightIsWireframe;
SetDrawer(aDrawer);
}
}
}
//=======================================================================
//function : GetHilightDisplayMode
//purpose : Query the current hilight display mode: Shading or Wireframe.
//=======================================================================
NIS_Surface::DisplayMode NIS_Surface::GetHilightDisplayMode () const
{
return myHilightIsWireframe ? Wireframe : Shading;
}
//=======================================================================
//function : ShowFreeBoundary
//purpose : Display free boundary of the surface object with the
// specified color
//=======================================================================
void NIS_Surface::ShowFreeBoundary (const Quantity_Color& theColor)
{
myIsShowFreeBoundary = Standard_True;
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myFreeEdgeColor = theColor;
SetDrawer (aDrawer);
// setDrawerUpdate(); - already called in SetDrawer()
}
//=======================================================================
//function : HideFreeBoundary
//purpose : Hides special precentation of free boundaries
//=======================================================================
void NIS_Surface::HideFreeBoundary ()
{
myIsShowFreeBoundary = Standard_False;
setDrawerUpdate();
}
//=======================================================================
@@ -532,19 +703,34 @@ void NIS_Surface::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
aNewObj->mypTriangles = (Standard_Integer *)theAlloc->Allocate(nBytes);
memcpy(aNewObj->mypTriangles, mypTriangles, nBytes);
}
aNewObj->myNEdges = myNEdges;
if (myNEdges > 0) {
aNewObj->mypEdges = static_cast<Standard_Integer **>
(theAlloc->Allocate(sizeof(Standard_Integer *) * myNEdges));
for (Standard_Integer i = 0; i < myNEdges; i++) {
const Standard_Integer * pEdge = mypEdges[i];
const Standard_Size nBytes = sizeof(Standard_Integer) * (pEdge[0] + 1);
aNewObj->mypEdges[i] =
static_cast<Standard_Integer *> (theAlloc->Allocate(nBytes));
memcpy(aNewObj->mypEdges[i], pEdge, nBytes);
}
}
myEdges.Clone(theAlloc, aNewObj->myEdges);
myFreeEdges.Clone(theAlloc, aNewObj->myFreeEdges);
aNewObj->myIsWireframe = myIsWireframe;
aNewObj->myIsShowFreeBoundary = myIsShowFreeBoundary;
aNewObj->myIsShowEdges = myIsShowEdges;
}
//=======================================================================
//function : NEdgeNodeInList
//purpose :
//=======================================================================
Standard_Integer NIS_Surface::NEdgeNodeInList (const Standard_Integer ind) const
{
return myEdges.NArrayIndexes(ind);
}
//=======================================================================
//function : NFreeEdgeNodeInList
//purpose :
//=======================================================================
Standard_Integer NIS_Surface::NFreeEdgeNodeInList
(const Standard_Integer ind) const
{
return myFreeEdges.NArrayIndexes(ind);
}
//=======================================================================
@@ -556,10 +742,22 @@ Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver) const
{
Standard_Real aResult (RealLast());
Standard_Real start[3], dir[3];
theAxis.Location().Coord(start[0], start[1], start[2]);
theAxis.Direction().Coord(dir[0], dir[1], dir[2]);
double anInter;
Standard_Real start[3], dir[3], anInter;
// Obtain the current Transformation from the Drawer
const Handle(NIS_SurfaceDrawer)& aDrawer =
static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
if (aDrawer.IsNull()) {
theAxis.Location().Coord(start[0], start[1], start[2]);
theAxis.Direction().Coord(dir[0], dir[1], dir[2]);
} else {
gp_Trsf aTrsf = aDrawer->GetTransformation();
aTrsf.Invert();
const gp_Ax1 anAxis = theAxis.Transformed(aTrsf);
anAxis.Location().Coord(start[0], start[1], start[2]);
anAxis.Direction().Coord(dir[0], dir[1], dir[2]);
}
if (myIsWireframe == Standard_False)
for (Standard_Integer i = 0; i < myNTriangles; i++) {
@@ -573,27 +771,100 @@ Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
aResult = anInter;
}
else {
const Standard_Real anOver2 = theOver*theOver;
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
const Standard_Integer * anEdge = mypEdges[iEdge];
const Standard_Integer nNodes = anEdge[0];
for (Standard_Integer i = 1; i < nNodes; i++) {
// Node index is incremented for the head of polygon indice array
if (NIS_Triangulated::seg_line_intersect (theAxis.Location().XYZ(),
theAxis.Direction().XYZ(),
anOver2,
&mypNodes[3*anEdge[i+0]],
&mypNodes[3*anEdge[i+1]],
&anInter))
if (anInter < aResult)
aResult = anInter;
}
}
anInter = intersectEdges(myEdges, theAxis, theOver);
if (anInter < aResult)
aResult = anInter;
anInter = intersectEdges(myFreeEdges, theAxis, theOver);
if (anInter < aResult)
aResult = anInter;
}
return aResult;
}
//=======================================================================
//function : Normal
//purpose :
//=======================================================================
Standard_Boolean NIS_Surface::Intersect (const gp_Ax1& theAxis, gp_Vec& theNormal) const
{
Standard_Real aResult (RealLast());
Standard_Real start[3], dir[3], anInter;
Standard_Integer anIndex(-1);
// Obtain the current Transformation from the Drawer
const Handle(NIS_SurfaceDrawer)& aDrawer =
static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
if (aDrawer.IsNull()) {
theAxis.Location().Coord(start[0], start[1], start[2]);
theAxis.Direction().Coord(dir[0], dir[1], dir[2]);
} else {
gp_Trsf aTrsf = aDrawer->GetTransformation();
aTrsf.Invert();
const gp_Ax1 anAxis = theAxis.Transformed(aTrsf);
anAxis.Location().Coord(start[0], start[1], start[2]);
anAxis.Direction().Coord(dir[0], dir[1], dir[2]);
}
if (myIsWireframe == Standard_False)
for (Standard_Integer i = 0; i < myNTriangles; i++) {
const Standard_Integer * pTri = &mypTriangles[3*i];
if (NIS_Triangulated::tri_line_intersect (start, dir,
&mypNodes[3*pTri[0]],
&mypNodes[3*pTri[1]],
&mypNodes[3*pTri[2]],
&anInter))
if (anInter < aResult) {
aResult = anInter;
anIndex = i;
}
}
if (anIndex < 0)
return Standard_False;
const Standard_Integer * pTri = &mypTriangles[3*anIndex];
gp_XYZ aPnt0(mypNodes[3*pTri[0]+0], mypNodes[3*pTri[0]+1], mypNodes[3*pTri[0]+2]);
gp_XYZ aPnt1(mypNodes[3*pTri[1]+0], mypNodes[3*pTri[1]+1], mypNodes[3*pTri[1]+2]);
gp_XYZ aPnt2(mypNodes[3*pTri[2]+0], mypNodes[3*pTri[2]+1], mypNodes[3*pTri[2]+2]);
theNormal.SetXYZ(((aPnt1 - aPnt0) ^ (aPnt2 - aPnt0)));
return Standard_True;
}
//=======================================================================
//function : intersectEdges
//purpose :
//=======================================================================
Standard_Real NIS_Surface::intersectEdges(const NIS_IndexLists& theEdges,
const gp_Ax1& theAxis,
const Standard_Real theOver) const
{
const Standard_Real anOver2 = theOver*theOver;
double anInter;
Standard_Real aResult (RealLast());
for (Standard_Integer iEdge = 0; iEdge < theEdges.NArrays(); iEdge++) {
const Standard_Integer * anEdge =
static_cast <Standard_Integer *>(theEdges.ArrayIndexes(iEdge));
const Standard_Integer nNodes = theEdges.NArrayIndexes(iEdge);
for (Standard_Integer i = 0; i < nNodes-1; i++) {
// Node index is incremented for the head of polygon indice array
if (NIS_Triangulated::seg_line_intersect (theAxis.Location().XYZ(),
theAxis.Direction().XYZ(),
anOver2,
&mypNodes[3*anEdge[i+0]],
&mypNodes[3*anEdge[i+1]],
&anInter))
if (anInter < aResult)
aResult = anInter;
}
}
return aResult;
}
//=======================================================================
//function : Intersect
//purpose :
@@ -604,6 +875,14 @@ Standard_Boolean NIS_Surface::Intersect (const Bnd_B3f& theBox,
const Standard_Boolean isFullIn) const
{
Standard_Boolean aResult (isFullIn);
gp_Trsf aTrsf = theTrf;
// Obtain the current Transformation from the Drawer
const Handle(NIS_SurfaceDrawer)& aDrawer =
static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
if (aDrawer.IsNull() == Standard_False)
aTrsf *= aDrawer->GetTransformation();
if (myIsWireframe == Standard_False) {
if (myNTriangles > 0) {
@@ -611,7 +890,7 @@ Standard_Boolean NIS_Surface::Intersect (const Bnd_B3f& theBox,
gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
static_cast<Standard_Real>(mypNodes[iNode+1]),
static_cast<Standard_Real>(mypNodes[iNode+2]));
theTrf.Transforms(aPnt);
aTrsf.Transforms(aPnt);
if (theBox.IsOut (aPnt) == isFullIn) {
aResult = !isFullIn;
break;
@@ -619,31 +898,48 @@ Standard_Boolean NIS_Surface::Intersect (const Bnd_B3f& theBox,
}
}
} else {
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
const Standard_Integer * anEdge = mypEdges[iEdge];
const Standard_Integer nNodes = anEdge[0];
for (Standard_Integer i = 1; i < nNodes; i++) {
// index is incremented by 1 for the head number in the array
gp_Pnt aPnt[2] = {
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
};
aPnt[0].Transform(theTrf);
aPnt[1].Transform(theTrf);
if (isFullIn) {
if (NIS_Triangulated::seg_box_included (theBox, aPnt) == 0) {
aResult = Standard_False;
break;
}
} else {
if (NIS_Triangulated::seg_box_intersect (theBox, aPnt)) {
aResult = Standard_True;
break;
}
aResult = intersectEdges(myEdges, aTrsf, theBox, isFullIn);
if(!aResult)
aResult = intersectEdges(myFreeEdges, aTrsf, theBox, isFullIn);
}
return aResult;
}
//=======================================================================
//function : intersectEdges
//purpose :
//=======================================================================
Standard_Boolean NIS_Surface::intersectEdges(const NIS_IndexLists& theEdges,
const gp_Trsf& theTrf,
const Bnd_B3f& theBox,
const Standard_Boolean isFullIn) const
{
Standard_Boolean aResult (isFullIn);
for (Standard_Integer iEdge = 0; iEdge < theEdges.NArrays(); iEdge++) {
const Standard_Integer * anEdge =
static_cast <Standard_Integer *>(theEdges.ArrayIndexes(iEdge));
const Standard_Integer nNodes = theEdges.NArrayIndexes(iEdge);
for (Standard_Integer i = 0; i < nNodes-1; i++) {
gp_Pnt aPnt[2] = {
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
};
aPnt[0].Transform(theTrf);
aPnt[1].Transform(theTrf);
if (isFullIn) {
if (NIS_Triangulated::seg_box_included (theBox, aPnt) == 0) {
aResult = Standard_False;
break;
}
} else {
if (NIS_Triangulated::seg_box_intersect (theBox, aPnt)) {
aResult = Standard_True;
break;
}
}
}
@@ -662,6 +958,14 @@ Standard_Boolean NIS_Surface::Intersect
const Standard_Boolean isFullIn) const
{
Standard_Boolean aResult (isFullIn);
gp_Trsf aTrsf = theTrf;
// Obtain the current Transformation from the Drawer
const Handle(NIS_SurfaceDrawer)& aDrawer =
static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
if (aDrawer.IsNull() == Standard_False)
aTrsf *= aDrawer->GetTransformation();
if (myIsWireframe == Standard_False) {
if (myNTriangles > 0) {
@@ -669,7 +973,7 @@ Standard_Boolean NIS_Surface::Intersect
gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
static_cast<Standard_Real>(mypNodes[iNode+1]),
static_cast<Standard_Real>(mypNodes[iNode+2]));
theTrf.Transforms(aPnt);
aTrsf.Transforms(aPnt);
gp_XY aP2d(aPnt.X(), aPnt.Y());
if (!NIS_Triangulated::IsIn(thePolygon, aP2d)) {
@@ -686,33 +990,52 @@ Standard_Boolean NIS_Surface::Intersect
}
}
} else {
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
const Standard_Integer * anEdge = mypEdges[iEdge];
const Standard_Integer nNodes = anEdge[0];
for (Standard_Integer i = 1; i < nNodes; i++) {
// index is incremented by 1 for the head number in the array
gp_Pnt aPnt[2] = {
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
};
aPnt[0].Transform(theTrf);
aPnt[1].Transform(theTrf);
const gp_XY aP2d[2] = { gp_XY(aPnt[0].X(), aPnt[0].Y()),
gp_XY(aPnt[1].X(), aPnt[1].Y()) };
if (isFullIn) {
if (NIS_Triangulated::seg_polygon_included (thePolygon, aP2d) == 0) {
aResult = Standard_False;
break;
}
} else {
if (NIS_Triangulated::seg_polygon_intersect (thePolygon, aP2d)) {
aResult = Standard_True;
break;
}
aResult = intersectEdges(myEdges, aTrsf, thePolygon, isFullIn);
if(!aResult)
aResult = intersectEdges(myFreeEdges, aTrsf, thePolygon, isFullIn);
}
return aResult;
}
//=======================================================================
//function : intersectEdges
//purpose :
//=======================================================================
Standard_Boolean NIS_Surface::intersectEdges
(const NIS_IndexLists& theEdges,
const gp_Trsf& theTrf,
const NCollection_List<gp_XY>& thePolygon,
const Standard_Boolean isFullIn) const
{
Standard_Boolean aResult (isFullIn);
for (Standard_Integer iEdge = 0; iEdge < theEdges.NArrays(); iEdge++)
{
const Standard_Integer * anEdge =
static_cast <Standard_Integer *>(theEdges.ArrayIndexes(iEdge));
const Standard_Integer nNodes = theEdges.NArrayIndexes(iEdge);
for (Standard_Integer i = 0; i < nNodes-1; i++) {
gp_Pnt aPnt[2] = {
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
};
aPnt[0].Transform(theTrf);
aPnt[1].Transform(theTrf);
const gp_XY aP2d[2] = { gp_XY(aPnt[0].X(), aPnt[0].Y()),
gp_XY(aPnt[1].X(), aPnt[1].Y()) };
if (isFullIn) {
if (NIS_Triangulated::seg_polygon_included (thePolygon, aP2d) == 0) {
aResult = Standard_False;
break;
}
} else {
if (NIS_Triangulated::seg_polygon_intersect (thePolygon, aP2d)) {
aResult = Standard_True;
break;
}
}
}

View File

@@ -17,6 +17,7 @@
#define NIS_Surface_HeaderFile
#include <NIS_InteractiveObject.hxx>
#include <NIS_IndexLists.hxx>
#include <NCollection_BaseAllocator.hxx>
#include <gp_XYZ.hxx>
@@ -39,14 +40,16 @@ class TopoDS_Shape;
* <p>
* This class is conceived as replacement of AIS_Shape; both wireframe and
* shading modes are available for dynamic switching.
* @ingroup nis_library
*/
class NIS_Surface : public NIS_InteractiveObject
{
public:
enum DisplayMode {
Wireframe,
Shading,
Wireframe
PureShading
};
/**
@@ -61,11 +64,14 @@ public:
* Source geometry. It should contain triangulations inside.
* @param theDeflection
* Absolute deflection for meshing 'theShape' if such meshing is needed.
* @param isFreeBnd
* To show or not to show the free boundary.
* @param theAl
* Allocator used for nodes and triangles in this presentation.
*/
Standard_EXPORT NIS_Surface(const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
Standard_EXPORT NIS_Surface(const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Boolean isFreeBnd=Standard_False,
const Handle_NCollection_BaseAllocator& theAl=0L);
/**
@@ -85,6 +91,18 @@ public:
*/
Standard_EXPORT void Clear ();
/**
* Query the number of nodes in Edge List.
*/
Standard_EXPORT Standard_Integer NEdgeNodeInList
(const Standard_Integer ind) const;
/**
* Query the number of nodes in Free Edge List.
*/
Standard_EXPORT Standard_Integer NFreeEdgeNodeInList
(const Standard_Integer ind) const;
/**
* Query the number of nodes.
*/
@@ -98,7 +116,12 @@ public:
/**
* Query the number of edges for wireframe display.
*/
inline Standard_Integer NEdges () const { return myNEdges; }
inline Standard_Integer NEdges () const { return myEdges.NArrays(); }
/**
* Query the number of free edges for wireframe display.
*/
inline Standard_Integer NFreeEdges () const { return myFreeEdges.NArrays(); }
/**
* Query the node by its index.
@@ -125,13 +148,23 @@ public:
/**
* Access to array of integers that represents an Edge.
* @return
* Pointer to array where the 0th element is the number of nodes in the edge
* and the elements starting from the 1st are node indices.
* Pointer to array without the 0 element.
*/
inline const Standard_Integer*
Edge (const Standard_Integer theIndex) const
{
return mypEdges[theIndex];
return static_cast <Standard_Integer *>(myEdges.ArrayIndexes(theIndex));
}
/**
* Access to array of integers that represents an Free Edge.
* @return
* Pointer to array without the 0 element.
*/
inline const Standard_Integer*
FreeEdge (const Standard_Integer theIndex) const
{
return static_cast <Standard_Integer *>(myFreeEdges.ArrayIndexes(theIndex));
}
/**
@@ -145,19 +178,20 @@ public:
return &mypNormals[theIndex * 3];
}
/**
* Returns status of displayin of free boundaries
*/
inline Standard_Boolean IsShowFreeBounds() const
{
return myIsShowFreeBoundary;
}
/**
* Create a default drawer instance.
*/
Standard_EXPORT virtual NIS_Drawer *
DefaultDrawer (NIS_Drawer *) const;
/**
* Set the normal color for presentation.
* @param theColor
* New color to use for the presentation.
*/
Standard_EXPORT void SetColor (const Quantity_Color& theColor);
/**
* Set the color for presentation of the back side of triangles.
* @param theColor
@@ -165,6 +199,12 @@ public:
*/
Standard_EXPORT void SetBackColor (const Quantity_Color& theColor);
/**
* Define the specularity that is the property of displayed material for both
* Front and Back faces. Can be in the range 0 to 1. Default value is 0.58
*/
Standard_EXPORT void SetSpecularity (const Standard_Real theValue);
/**
* Set the offset for the presentation.
* @param theValue
@@ -172,6 +212,14 @@ public:
*/
Standard_EXPORT void SetPolygonOffset (const Standard_Real theValue);
/**
* Set the transformation for this object.
* This method is suitable if you need to define transformation for
* individual NIS_Surface. For a group of NIS_Surface instances you can
* consider the correspondin method of NIS_SurfaceDrawer (it will be faster)
*/
Standard_EXPORT void SetTransformation(const gp_Trsf& theTrsf);
/**
* Set the display mode: Shading or Wireframe.
* The default mode is Shading.
@@ -184,6 +232,32 @@ public:
Standard_EXPORT DisplayMode
GetDisplayMode () const;
/**
* Set the hilight display mode: Shading or Wireframe.
* The default mode is Shading.
* NOTE: this Function works only in a shading mode when rendering the shape.
* If the Shape is rendered in Wireframe mode - the hilight display mode
* is wireframe
*/
Standard_EXPORT void SetHilightDisplayMode (const DisplayMode theMode);
/**
* Query the current hilight display mode: Shading or Wireframe.
*/
Standard_EXPORT DisplayMode
GetHilightDisplayMode () const;
/**
* Display free boundary of the surface object with the
* specified color
*/
Standard_EXPORT void ShowFreeBoundary (const Quantity_Color& theColor);
/**
* Hides special precentation of free boundaries
*/
Standard_EXPORT void HideFreeBoundary ();
/**
* Create a copy of theObject except its ID.
* @param theAll
@@ -193,8 +267,8 @@ public:
* passed NULL then the target should be created.
*/
Standard_EXPORT virtual void
Clone (const Handle_NCollection_BaseAllocator& theAll,
Handle_NIS_InteractiveObject& theDest) const;
Clone (const Handle_NCollection_BaseAllocator& theAll,
Handle_NIS_InteractiveObject& theDest) const;
/**
* Intersect the surface shading/wireframe geometry with a line/ray.
@@ -208,8 +282,22 @@ public:
* on the ray. May be negative.
*/
Standard_EXPORT virtual Standard_Real
Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver) const;
Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver) const;
/**
* Query the normal vector at the intersection point of the surface shading
* geometry with a line/ray.
* @param theAxis
* The line or ray in 3D space.
* @param theNormal
* The normal direction of intersected triangle.
* @return
* True if intersection is found and normal direction is computed.
*/
Standard_EXPORT Standard_Boolean
Intersect (const gp_Ax1& theAxis,
gp_Vec& theNormal) const;
/**
* Intersect the surface shading/wireframe geometry with an oriented box.
@@ -220,12 +308,12 @@ public:
* @param isFull
* True if full inclusion is required, False - if partial.
* @return
* True if the InteractiveObject geometry intersects the box or is inside it
* True if the InteractiveObject geometry intersects or is inside the box.
*/
Standard_EXPORT virtual Standard_Boolean
Intersect (const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean isFull)const;
Intersect (const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean isFull) const;
/**
* Intersect the surface shading/wireframe geometry with a selection polygon.
@@ -241,10 +329,10 @@ public:
* True if the InteractiveObject geometry intersects the polygon or is
* inside it
*/
Standard_EXPORT virtual Standard_Boolean Intersect
(const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean isFullIn) const;
Standard_EXPORT virtual Standard_Boolean
Intersect (const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean isFullIn) const;
protected:
@@ -262,8 +350,38 @@ protected:
* Compute normal to the surface at the node with the given index.
* Returns true if the vertex is artificial at this node.
*/
Standard_Boolean computeNormal (Standard_Integer theIndex,
gp_XYZ& theNormal) const;
Standard_EXPORT Standard_Boolean
computeNormal (Standard_Integer theIndex,
gp_XYZ& theNormal) const;
/**
* Auxiulary function computing intersection of an axis with edges.
* This function is used in "intersect" functions.
*/
Standard_EXPORT Standard_Real
intersectEdges(const NIS_IndexLists& theEdges,
const gp_Ax1& theAxis,
const Standard_Real theOver) const;
/**
* Auxiulary function computing intersection of an box (2d rectangle) with
* edges. This function is used in "intersect" functions.
*/
Standard_EXPORT Standard_Boolean
intersectEdges(const NIS_IndexLists& theEdges,
const gp_Trsf& theTrf,
const Bnd_B3f& theBox,
const Standard_Boolean isFullIn)const;
/**
* Auxiulary function computing intersection of a 2d polygon with edges.
* This function is used in "intersect" functions.
*/
Standard_EXPORT Standard_Boolean
intersectEdges(const NIS_IndexLists& theEdges,
const gp_Trsf& theTrf,
const NCollection_List<gp_XY> &thePolyg,
const Standard_Boolean isFullIn)const;
private:
Handle_NCollection_BaseAllocator myAlloc;
@@ -274,12 +392,16 @@ private:
//! Array of triangles (node indices)
Standard_Integer * mypTriangles;
//! Array of edges, each edge is an array of indices prefixed by N nodes
Standard_Integer ** mypEdges;
NIS_IndexLists myEdges;
//! Array of free edges, each edge is an array of indices prefixed by N nodes
NIS_IndexLists myFreeEdges;
//! Number of nodes in triangles
Standard_Integer myNNodes;
Standard_Integer myNTriangles;
Standard_Integer myNEdges;
Standard_Boolean myIsWireframe;
Standard_Integer myNTriangles : 28;
Standard_Boolean myIsWireframe : 1;
Standard_Boolean myHilightIsWireframe : 1;
Standard_Boolean myIsShowFreeBoundary : 1;
Standard_Boolean myIsShowEdges : 1;
public:
// Declaration of CASCADE RTTI

View File

@@ -20,10 +20,10 @@
#include <OpenGl_GlCore11.hxx>
static void setColor(GLenum theFace,
Quantity_Parameter * theAmbient,
const Standard_Real theSpecularity,
GLint theShininess);
static void setColor(Quantity_Parameter * theAmbientFront,
Quantity_Parameter * theAmbientBack,
const Standard_ShortReal theSpecularity,
GLint theShininess);
IMPLEMENT_STANDARD_HANDLE (NIS_SurfaceDrawer, NIS_Drawer)
IMPLEMENT_STANDARD_RTTIEXT (NIS_SurfaceDrawer, NIS_Drawer)
@@ -37,27 +37,17 @@ NIS_SurfaceDrawer::NIS_SurfaceDrawer
(const Quantity_Color &theNormal,
const Quantity_Color &theHilight,
const Quantity_Color &theDynHilight)
: myBackColor (theNormal),
myPolygonOffset (0.f),
myIsWireframe (Standard_False)
: NIS_Drawer(theHilight, theDynHilight),
myBackColor (theNormal),
myFreeEdgeColor (theNormal),
mySpecularity (0.58f),
myPolygonOffset (0.f),
myIsWireframe (Standard_False),
myHilightIsWireframe(Standard_False),
myIsShowEdges (Standard_True)
{
myColor[Draw_Normal] = theNormal;
myColor[Draw_Top] = theNormal;
myColor[Draw_Transparent] = theNormal;
myColor[Draw_Hilighted] = theHilight;
myColor[Draw_DynHilighted] = theDynHilight;
}
//=======================================================================
//function : SetColor
//purpose :
//=======================================================================
void NIS_SurfaceDrawer::SetColor(const Quantity_Color &theColor)
{
myColor[Draw_Normal] = theColor;
myColor[Draw_Top] = theColor;
myColor[Draw_Transparent] = theColor;
SetColor(Draw_Normal, theNormal);
myObjPerDrawer = 4;
}
//=======================================================================
@@ -71,14 +61,14 @@ void NIS_SurfaceDrawer::Assign (const Handle_NIS_Drawer& theOther)
NIS_Drawer::Assign (theOther);
const Handle(NIS_SurfaceDrawer)& anOther =
static_cast <const Handle(NIS_SurfaceDrawer)&> (theOther);
myColor[Draw_Normal] = anOther->myColor[Draw_Normal];
myColor[Draw_Top] = anOther->myColor[Draw_Top];
myColor[Draw_Transparent] = anOther->myColor[Draw_Transparent];
myColor[Draw_Hilighted] = anOther->myColor[Draw_Hilighted];
myColor[Draw_DynHilighted] = anOther->myColor[Draw_DynHilighted];
myBackColor = anOther->myBackColor;
myFreeEdgeColor = anOther->myFreeEdgeColor;
mySpecularity = anOther->mySpecularity;
myPolygonOffset = anOther->myPolygonOffset;
myIsWireframe = anOther->myIsWireframe;
myIsWireframe = anOther->myIsWireframe;
myHilightIsWireframe = anOther->myHilightIsWireframe;
myIsShowEdges = anOther->myIsShowEdges;
myTrsf = anOther->myTrsf;
}
}
@@ -90,20 +80,19 @@ void NIS_SurfaceDrawer::Assign (const Handle_NIS_Drawer& theOther)
Standard_Boolean NIS_SurfaceDrawer::IsEqual
(const Handle_NIS_Drawer& theOther)const
{
static const Standard_Real anEpsilon2 (1e-7);
Standard_Boolean aResult (Standard_False);
const Handle(NIS_SurfaceDrawer) anOther =
Handle(NIS_SurfaceDrawer)::DownCast (theOther);
if (NIS_Drawer::IsEqual(theOther))
aResult = (anOther->myColor[Draw_Normal]
.SquareDistance (myColor[Draw_Normal]) < anEpsilon2 &&
anOther->myColor[Draw_Hilighted]
.SquareDistance (myColor[Draw_Hilighted]) < anEpsilon2 &&
anOther->myColor[Draw_DynHilighted]
.SquareDistance (myColor[Draw_DynHilighted]) < anEpsilon2 &&
anOther->myBackColor.SquareDistance(myBackColor) < anEpsilon2 &&
aResult = (areEqual(anOther->myBackColor, myBackColor) &&
areEqual(anOther->myFreeEdgeColor, myFreeEdgeColor) &&
fabs(anOther->mySpecularity - mySpecularity) < 0.01 &&
fabs(anOther->myPolygonOffset - myPolygonOffset) < 0.999 &&
myIsWireframe == anOther->myIsWireframe);
myIsWireframe == anOther->myIsWireframe &&
myHilightIsWireframe == anOther->myHilightIsWireframe &&
myIsShowEdges == anOther->myIsShowEdges &&
fabs(anOther->myTrsf.TranslationPart().SquareModulus() -
myTrsf.TranslationPart().SquareModulus()) < 0.0001);
if (aResult) {
// Arbitrary point for test
gp_XYZ aPnt[2] = {
@@ -112,7 +101,7 @@ Standard_Boolean NIS_SurfaceDrawer::IsEqual
};
anOther->myTrsf.Transforms(aPnt[0]);
myTrsf.Transforms(aPnt[1]);
if ((aPnt[0] - aPnt[1]).SquareModulus() > anEpsilon2)
if ((aPnt[0] - aPnt[1]).SquareModulus() > 1e-6)
aResult = Standard_False;
}
return aResult;
@@ -152,7 +141,6 @@ void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType,
const NIS_DrawList&)
{
glEnable(GL_LIGHTING);
// glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
glEnableClientState (GL_VERTEX_ARRAY);
if (myIsWireframe == Standard_False) {
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
@@ -160,24 +148,45 @@ void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType,
glShadeModel(GL_SMOOTH);
}
Quantity_Parameter aValueCol[4] = {0., 0., 0., 1.};
Quantity_Parameter aValueCol[][4] = {
{0., 0., 0., 1. - myTransparency}, // front color
{0., 0., 0., 1. - myTransparency} // back color
};
Quantity_Color aBackColor = myBackColor;
Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
GLfloat aLineWidth (1.f);
GLfloat anOffset = myPolygonOffset;
static const GLfloat gColorN[4] = {0.f, 0.f, 0.f, 1.f};
DrawType aDrawType = theType;
myIsBlend = Standard_False;
switch (theType) {
case Draw_DynHilighted:
aLineWidth = 3.f;
myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.1, 5);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
glLineWidth (aLineWidth);
if (myIsWireframe == Standard_False)
glPolygonOffset(1.f, -(anOffset + 11.f));
return;
case Draw_Hilighted:
if (myHilightIsWireframe)
{
aDrawType = Draw_Normal;
glEnableClientState (GL_NORMAL_ARRAY);
if (myTransparency > 0.) {
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// don't write triangles into depth test
glDepthMask(GL_FALSE);
myIsBlend = Standard_True;
}
case Draw_DynHilighted:
aLineWidth = 3.f;
GetColor(aDrawType).Values(aValueCol[0][0], aValueCol[0][1],
aValueCol[0][2], bidTC);
aBackColor.Values(aValueCol[1][0],aValueCol[1][1],aValueCol[1][2], bidTC);
setColor(aValueCol[0], aValueCol[1], mySpecularity, 10);
glLineWidth (aLineWidth);
if (myIsWireframe == Standard_False)
glPolygonOffset(1.f, -(anOffset + 11.f));
return;
}
anOffset += 10.f;
aBackColor = GetColor(theType);
case Draw_Normal:
case Draw_Top:
case Draw_Transparent:
@@ -185,29 +194,23 @@ void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType,
glPolygonOffset(1.f, -anOffset);
glEnableClientState (GL_NORMAL_ARRAY);
}
myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
aValueCol[3] = 1. - myTransparency;
GetColor(theType).Values(aValueCol[0][0], aValueCol[0][1],
aValueCol[0][2], bidTC);
aBackColor.Values(aValueCol[1][0], aValueCol[1][1], aValueCol[1][2], bidTC);
if (theType == Draw_Transparent) {
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// don't write triangles into depth test
glDepthMask(GL_FALSE);
myIsBlend = Standard_True;
}
break;
default:
return;
}
// glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
if (theType == Draw_Hilighted ||
myBackColor.SquareDistance(myColor[Draw_Normal]) < 1.e-7)
{
setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.5, 10);
} else {
setColor(GL_FRONT, &aValueCol[0], 0.4, 10);
myBackColor.Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
setColor(GL_BACK, &aValueCol[0], 0.8, 5);
}
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
setColor(aValueCol[0], aValueCol[1], mySpecularity, 10);
glLineWidth (aLineWidth);
}
@@ -221,17 +224,23 @@ void NIS_SurfaceDrawer::AfterDraw (const DrawType theType,
{
glDisable(GL_LIGHTING);
glDisableClientState(GL_VERTEX_ARRAY);
switch (theType) {
case Draw_Transparent:
if (theType != Draw_DynHilighted)
{
if (myIsBlend)
{
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
case Draw_Hilighted:
case Draw_Normal:
case Draw_Top:
if (myIsWireframe == Standard_False)
glDisableClientState(GL_NORMAL_ARRAY);
default:;
glDisable(GL_CULL_FACE);
if (theType == Draw_Hilighted)
{
glDepthMask (GL_TRUE);
}
}
if (myIsWireframe == Standard_False)
{
glDisableClientState(GL_NORMAL_ARRAY);
}
}
if (myIsWireframe == Standard_False)
glDisable(GL_POLYGON_OFFSET_FILL);
}
@@ -258,23 +267,67 @@ void NIS_SurfaceDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
// In Highlited mode the shape must be shown as wireframe
Standard_Boolean isWireframe(myIsWireframe);
if (isWireframe == Standard_False && theType == Draw_DynHilighted)
if (pObject->NEdges() > 0)
if (pObject->NEdges() > 0 || pObject->NFreeEdges() > 0)
isWireframe = Standard_True;
if (isWireframe)
{
for (Standard_Integer i = 0; i < pObject->NEdges(); i++) {
const GLint * pEdge = static_cast<const GLint *> (pObject->Edge(i));
glDrawElements (GL_LINE_STRIP, pEdge[0], GL_UNSIGNED_INT, &pEdge[1]);
}
} else {
if (!isWireframe)
{
if (pObject->NTriangles()) {
if (theType != Draw_DynHilighted)
glNormalPointer (GL_FLOAT, 0, pObject->Normal(0));
if (myIsBlend) {
// Drawing BACK faces before FRONT ones improves the transparency
glCullFace(GL_FRONT);
glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
GL_UNSIGNED_INT, pObject->Triangle(0));
glCullFace(GL_BACK);
}
glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
GL_UNSIGNED_INT, pObject->Triangle(0));
}
}
if (myIsShowEdges || isWireframe || pObject->IsShowFreeBounds() ||
(theType == Draw_Hilighted && myHilightIsWireframe == Standard_True))
{
if (pObject->NEdges() > 0 || pObject->NFreeEdges() > 0) {
glDisable (GL_LIGHTING);
Quantity_Parameter R1, R2, R3;
GetColor(theType).Values(R1, R2, R3, Quantity_TOC_RGB);
glColor3d (R1, R2, R3);
drawEdges(pObject, theType);
glEnable (GL_LIGHTING);
}
}
}
//=======================================================================
//function : drawEdges
//purpose :
//=======================================================================
void NIS_SurfaceDrawer::drawEdges (const NIS_Surface * pObject,
const DrawType theType)
{
// Draw non-free edges
for (Standard_Integer i = 0; i < pObject->NEdges(); i++) {
glDrawElements (GL_LINE_STRIP, pObject->NEdgeNodeInList(i),
GL_UNSIGNED_INT, pObject->Edge(i));
}
// Set color to show free edges, if they are requested
if (pObject->IsShowFreeBounds() && theType != Draw_DynHilighted &&
!(theType == Draw_Hilighted && myHilightIsWireframe == Standard_True))
{
Quantity_Parameter R1, R2, R3;
myFreeEdgeColor.Values(R1, R2, R3, Quantity_TOC_RGB);
glColor3d (R1, R2, R3);
glLineWidth (2.5f);
}
// Draw free edges
for (Standard_Integer i = 0; i < pObject->NFreeEdges(); i++)
glDrawElements (GL_LINE_STRIP, pObject->NFreeEdgeNodeInList(i),
GL_UNSIGNED_INT, pObject->FreeEdge(i));
}
//=======================================================================
@@ -282,24 +335,38 @@ void NIS_SurfaceDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
//purpose :
//=======================================================================
void setColor(GLenum theFace,
Quantity_Parameter * theAmbient,
const Standard_Real theSpecularity,
GLint theShininess)
void setColor(Quantity_Parameter * theAmbientFront,
Quantity_Parameter * theAmbientBack,
const Standard_ShortReal theSpecularity,
GLint theShininess)
{
GLfloat aSpec = static_cast<GLfloat>(theSpecularity);
static const GLfloat gColorN[4] = {0.f, 0.f, 0.f, 1.f};
GLfloat aValueCol[4] = {
GLfloat(theAmbient[0]),
GLfloat(theAmbient[1]),
GLfloat(theAmbient[2]),
GLfloat(theAmbient[3])
GLfloat(theAmbientFront[0]),
GLfloat(theAmbientFront[1]),
GLfloat(theAmbientFront[2]),
GLfloat(theAmbientFront[3])
};
glMaterialfv(theFace, GL_AMBIENT_AND_DIFFUSE, &aValueCol[0]);
aValueCol[0] = aSpec * (aValueCol[0] - 1.f) + 1.f;
aValueCol[1] = aSpec * (aValueCol[1] - 1.f) + 1.f;
aValueCol[2] = aSpec * (aValueCol[2] - 1.f) + 1.f;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, &aValueCol[0]);
aValueCol[0] = GLfloat(theAmbientBack[0]);
aValueCol[1] = GLfloat(theAmbientBack[1]);
aValueCol[2] = GLfloat(theAmbientBack[2]);
aValueCol[3] = GLfloat(theAmbientBack[3]);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, &aValueCol[0]);
const GLfloat aSpec(theSpecularity < 0. ? 0.f :
theSpecularity > 1.f ? 1.f :
theSpecularity);
aValueCol[0] = aSpec;
aValueCol[1] = aSpec;
aValueCol[2] = aSpec;
aValueCol[3] = 1.f;
glMaterialfv(theFace, GL_SPECULAR, &aValueCol[0]);
glMateriali(theFace, GL_SHININESS, theShininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, &aValueCol[0]);
glMateriali(GL_FRONT, GL_SHININESS, theShininess);
glMaterialfv(GL_BACK, GL_SPECULAR, &aValueCol[0]);
glMateriali(GL_BACK, GL_SHININESS, theShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, &gColorN[0]);
glMaterialfv(GL_BACK, GL_EMISSION, &gColorN[0]);
}

View File

@@ -18,12 +18,13 @@
#include <NIS_Drawer.hxx>
#include <gp_Trsf.hxx>
#include <Quantity_Color.hxx>
//#include <Quantity_Color.hxx>
class NIS_Surface;
/**
* Drawer for interactive object type NIS_Surface.
* @ingroup nis_library
*/
class NIS_SurfaceDrawer : public NIS_Drawer
@@ -40,11 +41,6 @@ class NIS_SurfaceDrawer : public NIS_Drawer
const Quantity_Color &theDynHilight
= Quantity_NOC_CYAN1);
/**
* Sets the color of the drawer.
*/
Standard_EXPORT void SetColor (const Quantity_Color &theColor);
/**
* Define the color used for the back side of rendered triangles.
* By default this color is the same as the 'Normal' color.
@@ -54,6 +50,15 @@ class NIS_SurfaceDrawer : public NIS_Drawer
myBackColor = theColor;
}
/**
* Define the specularity that is the property of displayed material for both
* Front and Back faces. Can be in the range 0 to 1. Default value is 0.58
*/
inline void SetSpecularity (const Standard_Real theValue)
{
mySpecularity = static_cast<Standard_ShortReal>(theValue);
}
/**
* Sets the transformation to the drawer.
*/
@@ -117,17 +122,26 @@ class NIS_SurfaceDrawer : public NIS_Drawer
Standard_EXPORT virtual Standard_Boolean
IsEqual (const Handle_NIS_Drawer& theOth)const;
protected:
protected:
Standard_EXPORT virtual void redraw (const DrawType theType,
const Handle_NIS_View& theView);
private:
void drawEdges (const NIS_Surface * pObject,
const DrawType theType);
private:
Quantity_Color myColor[5];
Quantity_Color myBackColor;
Quantity_Color myFreeEdgeColor;
Standard_ShortReal mySpecularity;
gp_Trsf myTrsf;
Standard_ShortReal myPolygonOffset;
Standard_Boolean myIsWireframe;
Standard_Boolean myIsWireframe;
Standard_Boolean myHilightIsWireframe;
Standard_Boolean myIsShowEdges;
Standard_Boolean myIsBlend; // defined and used internally
friend class NIS_Surface;

210
src/NIS/NIS_Text.cxx Normal file
View File

@@ -0,0 +1,210 @@
// File: NIS_Text.cxx
// Created: 12.12.11 07:16
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2011
#include <NIS_Text.hxx>
#include <NIS_TextDrawer.hxx>
IMPLEMENT_STANDARD_HANDLE (NIS_Text, NIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT (NIS_Text, NIS_InteractiveObject)
//=======================================================================
//function : NIS_Text()
//purpose : Constructor
//=======================================================================
NIS_Text::NIS_Text (const char * theText)
: myText (theText? theText : ""),
myPosition (gp_XYZ(0., 0., 0.))
{
}
//=======================================================================
//function : SetText
//purpose : Initialization with a text string
//=======================================================================
void NIS_Text::SetText (const char * theText)
{
myText = theText;
if (GetDrawer().IsNull() == Standard_False)
setDrawerUpdate();
}
//=======================================================================
//function : SetPosition
//purpose : Initialization with the text position
//=======================================================================
void NIS_Text::SetPosition (const gp_XYZ& thePosition)
{
myPosition = thePosition;
if (GetDrawer().IsNull() == Standard_False)
setDrawerUpdate();
}
//=======================================================================
//function : SetFontFamily
//purpose : Define the font type (family).
//=======================================================================
void NIS_Text::SetFontFamily (const FontFamily theFamily)
{
const Handle(NIS_TextDrawer) aDrawer =
static_cast<NIS_TextDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myFontFamily = theFamily;
const NIS_TextDrawer * pDrawer =
static_cast<const NIS_TextDrawer *>(SetDrawer(aDrawer).operator->());
pDrawer->SetFontUpdated();
}
//=======================================================================
//function : SetFontWeight
//purpose : Define the font weight.
//=======================================================================
void NIS_Text::SetFontWeight (const FontWeight theWeight)
{
const Handle(NIS_TextDrawer) aDrawer =
static_cast<NIS_TextDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myFontWeight = theWeight;
const NIS_TextDrawer * pDrawer =
static_cast<const NIS_TextDrawer *>(SetDrawer(aDrawer).operator->());
pDrawer->SetFontUpdated();
}
//=======================================================================
//function : SetFontCharset
//purpose : Define the charset of the created font.
//=======================================================================
void NIS_Text::SetFontCharset (const FontCharset theCharset)
{
const Handle(NIS_TextDrawer) aDrawer =
static_cast<NIS_TextDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myFontCharset = theCharset;
const NIS_TextDrawer * pDrawer =
static_cast<const NIS_TextDrawer *>(SetDrawer(aDrawer).operator->());
pDrawer->SetFontUpdated();
}
//=======================================================================
//function : SetFontHeight
//purpose : Define the character height in pixels.
//=======================================================================
void NIS_Text::SetFontHeight (const Standard_Integer theValue)
{
const Handle(NIS_TextDrawer) aDrawer =
static_cast<NIS_TextDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myFontHeight = theValue;
const NIS_TextDrawer * pDrawer =
static_cast<const NIS_TextDrawer *>(SetDrawer(aDrawer).operator->());
pDrawer->SetFontUpdated();
}
//=======================================================================
//function : SetFontAngle
//purpose : Define the angle of the text relative to OX.
//=======================================================================
void NIS_Text::SetFontAngle (const Standard_Real theValue)
{
const Handle(NIS_TextDrawer) aDrawer =
static_cast<NIS_TextDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myFontAngle =
static_cast<Standard_Integer>(0.1 + (theValue * 1800) / M_PI);
const NIS_TextDrawer * pDrawer =
static_cast<const NIS_TextDrawer *>(SetDrawer(aDrawer).operator->());
pDrawer->SetFontUpdated();
}
//=======================================================================
//function : SetItalic
//purpose : Defines if italic font type to use.
//=======================================================================
void NIS_Text::SetItalic (const Standard_Boolean isItalic)
{
const Handle(NIS_TextDrawer) aDrawer =
static_cast<NIS_TextDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myIsItalic = isItalic;
const NIS_TextDrawer * pDrawer =
static_cast<const NIS_TextDrawer *>(SetDrawer(aDrawer).operator->());
pDrawer->SetFontUpdated();
}
//=======================================================================
//function : SetUnderline
//purpose : Defines if Underline font to use.
//=======================================================================
void NIS_Text::SetUnderline (const Standard_Boolean isUnderline)
{
const Handle(NIS_TextDrawer) aDrawer =
static_cast<NIS_TextDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myIsUnderline = isUnderline;
const NIS_TextDrawer * pDrawer =
static_cast<const NIS_TextDrawer *>(SetDrawer(aDrawer).operator->());
pDrawer->SetFontUpdated();
}
//=======================================================================
//function : DefaultDrawer
//purpose : Create a default drawer instance.
//=======================================================================
NIS_Drawer * NIS_Text::DefaultDrawer (NIS_Drawer * theDrawer) const
{
if (!theDrawer)
theDrawer = new NIS_TextDrawer;
return theDrawer;
}
//=======================================================================
//function : Clone
//purpose :
//=======================================================================
void NIS_Text::Clone (const Handle_NCollection_BaseAllocator& theAllocator,
Handle_NIS_InteractiveObject& theDest) const
{
Handle(NIS_Text) aNewObj;
if (theDest.IsNull()) {
aNewObj = new NIS_Text();
theDest = aNewObj;
} else {
aNewObj = reinterpret_cast<NIS_Text*> (theDest.operator->());
}
NIS_InteractiveObject::Clone(theAllocator, theDest);
aNewObj->myText = myText;
aNewObj->myPosition = myPosition;
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Real NIS_Text::Intersect (const gp_Ax1& /*theAxis*/,
const Standard_Real /*theOver*/) const
{
return RealLast();
}
//=======================================================================
//function : computeBox
//purpose : empty method
//=======================================================================
void NIS_Text::computeBox ()
{
}

177
src/NIS/NIS_Text.hxx Normal file
View File

@@ -0,0 +1,177 @@
// File: NIS_Text.hxx
// Created: 12.12.11 06:54
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2011
#ifndef NIS_Text_HeaderFile
#define NIS_Text_HeaderFile
#include <NIS_InteractiveObject.hxx>
#include <TCollection_AsciiString.hxx>
#include <gp_XYZ.hxx>
class NIS_TextDrawer;
/**
* Bitmap Text presentation.
* @ingroup nis_library
*/
class NIS_Text : public NIS_InteractiveObject
{
public:
enum FontFamily {
FontFamily_DEFAULT = 0,
FontFamily_Decorative,
FontFamily_Modern,
FontFamily_Roman,
FontFamily_Script,
FontFamily_Swiss,
FontFamily_Times,
FontFamily_Helvetica,
FontFamily_Lucida,
FontFamily_Courier,
FontFamily_Symbol
};
enum FontWeight {
FontWeight_DEFAULT = 0,
FontWeight_Thin,
FontWeight_Extralight,
FontWeight_Ultralight,
FontWeight_Light,
FontWeight_Book,
FontWeight_Normal,
FontWeight_Regular,
FontWeight_Medium,
FontWeight_Semibold,
FontWeight_Demibold,
FontWeight_Bold,
FontWeight_Extrabold,
FontWeight_Ultrabold,
FontWeight_Heavy,
FontWeight_Black
};
enum FontCharset {
FontCharset_DEFAULT = 0,
FontCharset_ANSI,
FontCharset_EastEurope,
FontCharset_Greek,
FontCharset_Russian,
FontCharset_Chinese,
FontCharset_Symbol,
FontCharset_Turkish,
FontCharset_Hebrew,
FontCharset_Arabic
};
public:
// ---------- PUBLIC METHODS ----------
/**
* Empty constructor.
*/
Standard_EXPORT NIS_Text (const char * theText = 0L);
/**
* Initialization with a text string
*/
Standard_EXPORT void SetText (const char * theText);
/**
* Initialization with the text position
*/
Standard_EXPORT void SetPosition (const gp_XYZ& thePosition);
/**
* Define the font type (family).
*/
Standard_EXPORT void SetFontFamily (const FontFamily theFamily);
/**
* Define the font weight.
*/
Standard_EXPORT void SetFontWeight (const FontWeight theWeight);
/**
* Define the charset of the created font.
*/
Standard_EXPORT void SetFontCharset (const FontCharset theCharset);
/**
* Define the character height in pixels.
*/
Standard_EXPORT void SetFontHeight (const Standard_Integer theValue);
/**
* Define the angle of the text relative to OX.
*/
Standard_EXPORT void SetFontAngle (const Standard_Real theValue);
/**
* Defines if italic font type to use.
*/
Standard_EXPORT void SetItalic
(const Standard_Boolean isItalic = Standard_True);
/**
* Defines if Underline font to use.
*/
Standard_EXPORT void SetUnderline
(const Standard_Boolean isUnderline = Standard_True);
/**
* Create a default drawer instance.
*/
Standard_EXPORT virtual NIS_Drawer *
DefaultDrawer (NIS_Drawer *) const;
/**
* Create a copy of theObject except its ID.
* @param theAll
* Allocator where the Dest should store its private data.
* @param theDest
* <tt>[in-out]</tt> The target object where the data are copied. If
* passed NULL then the target should be created.
*/
Standard_EXPORT virtual void
Clone (const Handle_NCollection_BaseAllocator& theAll,
Handle_NIS_InteractiveObject& theDest) const;
/**
* Intersect method - empty implementation.
*/
Standard_EXPORT virtual Standard_Real
Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver) const;
protected:
// ---------- PROTECTED METHODS ----------
/**
* Create a 3D bounding box of the object.
*/
Standard_EXPORT virtual void
computeBox ();
private:
// ---------- PRIVATE FIELDS ----------
TCollection_AsciiString myText;
gp_XYZ myPosition;
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_Text)
friend class NIS_TextDrawer;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_Text, NIS_InteractiveObject)
#endif

297
src/NIS/NIS_TextDrawer.cxx Normal file
View File

@@ -0,0 +1,297 @@
// File: NIS_TextDrawer.cxx
// Created: 12.12.11 07:37
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2011
#include <NIS_TextDrawer.hxx>
#ifdef WNT
#ifdef NOGDI
#undef NOGDI
#endif
#ifdef NOUSER
#undef NOUSER
#endif
#include <windows.h>
#endif
#include <GL/gl.h>
IMPLEMENT_STANDARD_HANDLE (NIS_TextDrawer, NIS_Drawer)
IMPLEMENT_STANDARD_RTTIEXT (NIS_TextDrawer, NIS_Drawer)
//=======================================================================
//function : NIS_TextDrawer()
//purpose : Constructor
//=======================================================================
NIS_TextDrawer::NIS_TextDrawer ( )
: myFontFamily (NIS_Text::FontFamily_DEFAULT),
myFontWeight (NIS_Text::FontWeight_Normal),
myFontCharset (NIS_Text::FontCharset_ANSI),
myFontHeight (18),
myFontAngle (0),
myIsItalic (Standard_False),
myIsUnderline (Standard_False)
{
SetCompiled(Standard_False);
}
//=======================================================================
//function : createDefaultList
//purpose :
//=======================================================================
NIS_DrawList* NIS_TextDrawer::createDefaultList
(const Handle_NIS_View& theView) const
{
return new DrawList(theView);
}
//=======================================================================
//function : SetListID
//purpose :
//=======================================================================
void NIS_TextDrawer::DrawList::SetListID (const NIS_Drawer::DrawType theType,
const Standard_Size nLists)
{
myListID[theType] = (Standard_Integer)glGenLists(nLists);
}
//=======================================================================
//function : Assign
//purpose :
//=======================================================================
void NIS_TextDrawer::Assign (const Handle_NIS_Drawer& theOther)
{
if (theOther.IsNull() == Standard_False) {
NIS_Drawer::Assign(theOther);
const Handle(NIS_TextDrawer)& anOther =
static_cast <const Handle(NIS_TextDrawer)&> (theOther);
myFontFamily = anOther->myFontFamily;
myFontWeight = anOther->myFontWeight;
myFontCharset = anOther->myFontCharset;
myFontHeight = anOther->myFontHeight;
myFontAngle = anOther->myFontAngle;
myIsItalic = anOther->myIsItalic;
myIsUnderline = anOther->myIsUnderline;
}
}
//=======================================================================
//function : IsEqual
//purpose :
//=======================================================================
Standard_Boolean NIS_TextDrawer::IsEqual
(const Handle_NIS_Drawer& theOther) const
{
Standard_Boolean aResult (Standard_False);
if (NIS_Drawer::IsEqual(theOther)) {
const Handle(NIS_TextDrawer) anOther =
Handle(NIS_TextDrawer)::DownCast(theOther);
aResult = (myFontFamily == anOther->myFontFamily &&
myFontWeight == anOther->myFontWeight &&
myFontCharset == anOther->myFontCharset &&
myFontHeight == anOther->myFontHeight &&
myFontAngle == anOther->myFontAngle &&
myIsItalic == anOther->myIsItalic &&
myIsUnderline == anOther->myIsUnderline);
}
return aResult;
}
//=======================================================================
//function : SetFontUpdated
//purpose :
//=======================================================================
void NIS_TextDrawer::SetFontUpdated () const
{
NCollection_List<NIS_DrawList*>::Iterator anIter(myLists);
for (; anIter.More(); anIter.Next()) {
DrawList* pList = static_cast<DrawList *>(anIter.Value());
if (pList)
pList->IsFontUpdated = Standard_True;
}
}
//=======================================================================
//function : BeforeDraw
//purpose :
//=======================================================================
void NIS_TextDrawer::BeforeDraw(const DrawType theType,
const NIS_DrawList& theDrawList)
{
// indicate start of glyph display lists
const DrawList& aList = static_cast<const DrawList&> (theDrawList);
if (aList.IsFontUpdated || aList.GetListID(Draw_Normal) == 0)
updateFontBitmaps(const_cast<DrawList&>(aList));
glListBase (aList.GetListID(Draw_Normal));
Quantity_Parameter aValue[4];
const Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
GetColor(theType).Values (aValue[0], aValue[1], aValue[2], bidTC);
aValue[3] = 1. - myTransparency;
if (theType == Draw_Transparent && myTransparency > 0.01) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glColor4d (aValue[0], aValue[1], aValue[2], aValue[3]);
glDisable(GL_LIGHTING);
}
//=======================================================================
//function : AfterDraw
//purpose :
//=======================================================================
void NIS_TextDrawer::AfterDraw(const DrawType theType,
const NIS_DrawList& /*theDrawList*/)
{
if (theType == Draw_Transparent && myTransparency > 0.01)
glDisable(GL_BLEND);
}
//=======================================================================
//function : Draw
//purpose : Display the given interactive object in the given view.
//=======================================================================
void NIS_TextDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
const DrawType /*theType*/,
const NIS_DrawList& /*theDrawList*/)
{
const NIS_Text * pObj = static_cast<const NIS_Text *>(theObj.operator->());
glRasterPos3d(pObj->myPosition.X(),pObj->myPosition.Y(),pObj->myPosition.Z());
// display a string:
glCallLists (pObj->myText.Length(), GL_UNSIGNED_BYTE,
pObj->myText.ToCString());
}
//=======================================================================
//function : updateFontBitmaps
//purpose :
//=======================================================================
void NIS_TextDrawer::updateFontBitmaps (NIS_TextDrawer::DrawList& theList)
{
if (theList.GetListID(Draw_Normal) == 0) {
theList.SetListID(Draw_Normal, 256);
}
#ifdef WNT
int aWeight, aFamily, aCharset;
switch (myFontWeight) {
default:
case NIS_Text::FontWeight_DEFAULT:
aWeight = FW_DONTCARE; break;
case NIS_Text::FontWeight_Thin:
aWeight = FW_THIN; break;
case NIS_Text::FontWeight_Extralight:
aWeight = FW_EXTRALIGHT; break;
case NIS_Text::FontWeight_Ultralight:
aWeight = FW_ULTRALIGHT; break;
case NIS_Text::FontWeight_Book:
case NIS_Text::FontWeight_Light:
aWeight = FW_LIGHT; break;
case NIS_Text::FontWeight_Normal:
aWeight = FW_NORMAL; break;
case NIS_Text::FontWeight_Regular:
aWeight = FW_REGULAR; break;
case NIS_Text::FontWeight_Medium:
aWeight = FW_MEDIUM; break;
case NIS_Text::FontWeight_Semibold:
aWeight = FW_SEMIBOLD; break;
case NIS_Text::FontWeight_Demibold:
aWeight = FW_DEMIBOLD; break;
case NIS_Text::FontWeight_Bold:
aWeight = FW_BOLD; break;
case NIS_Text::FontWeight_Extrabold:
aWeight = FW_EXTRABOLD; break;
case NIS_Text::FontWeight_Ultrabold:
aWeight = FW_ULTRABOLD; break;
case NIS_Text::FontWeight_Heavy:
aWeight = FW_HEAVY; break;
case NIS_Text::FontWeight_Black:
aWeight = FW_BLACK; break;
}
switch (myFontFamily) {
case NIS_Text::FontFamily_Decorative:
aFamily = FF_DECORATIVE; break;
case NIS_Text::FontFamily_Courier:
case NIS_Text::FontFamily_Modern:
aFamily = FF_MODERN; break;
case NIS_Text::FontFamily_Times:
case NIS_Text::FontFamily_Roman:
aFamily = FF_ROMAN; break;
case NIS_Text::FontFamily_Lucida:
case NIS_Text::FontFamily_Script:
aFamily = FF_SCRIPT; break;
case NIS_Text::FontFamily_Helvetica:
case NIS_Text::FontFamily_Swiss:
aFamily = FF_SWISS; break;
case NIS_Text::FontFamily_Symbol:
default:
case NIS_Text::FontFamily_DEFAULT:
aFamily = FF_DONTCARE; break;
}
switch (myFontCharset) {
case NIS_Text::FontCharset_ANSI:
aCharset = ANSI_CHARSET; break;
case NIS_Text::FontCharset_EastEurope:
aCharset = EASTEUROPE_CHARSET; break;
case NIS_Text::FontCharset_Greek:
aCharset = GREEK_CHARSET; break;
case NIS_Text::FontCharset_Russian:
aCharset = RUSSIAN_CHARSET; break;
case NIS_Text::FontCharset_Chinese:
aCharset = CHINESEBIG5_CHARSET; break;
case NIS_Text::FontCharset_Symbol:
aCharset = SYMBOL_CHARSET; break;
case NIS_Text::FontCharset_Turkish:
aCharset = TURKISH_CHARSET; break;
case NIS_Text::FontCharset_Hebrew:
aCharset = HEBREW_CHARSET; break;
case NIS_Text::FontCharset_Arabic:
aCharset = ARABIC_CHARSET; break;
default:
case NIS_Text::FontCharset_DEFAULT:
aCharset = DEFAULT_CHARSET; break;
}
// create font
HFONT hFont = ::CreateFont
(myFontHeight,
0, // character width
myFontAngle, // angle
0, // orientation
aWeight,
(DWORD)myIsItalic,
(DWORD)myIsUnderline,
FALSE, // strikeout
aCharset,
OUT_TT_PRECIS, // output precision (TrueType font)
CLIP_DEFAULT_PRECIS, // clipping precision (default)
NONANTIALIASED_QUALITY, // output quality
aFamily, // pitch and family
NULL); // face name
HDC hdc = GetDC(NULL); // screen device
HGDIOBJ aPrev = ::SelectObject(hdc, hFont);
// SelectObject (hdc, GetStockObject (SYSTEM_FONT));
// create the bitmap display lists
// we're making images of glyphs 0 thru 255
wglUseFontBitmaps (hdc, 0, 255, theList.GetListID(Draw_Normal));
aPrev = ::SelectObject(hdc, aPrev);
::DeleteObject(aPrev);
::ReleaseDC(NULL, hdc);
#endif
theList.IsFontUpdated = Standard_False;
}

104
src/NIS/NIS_TextDrawer.hxx Normal file
View File

@@ -0,0 +1,104 @@
// File: NIS_TextDrawer.hxx
// Created: 12.12.11 07:31
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2011
#ifndef NIS_TextDrawer_HeaderFile
#define NIS_TextDrawer_HeaderFile
#include <NIS_Drawer.hxx>
#include <NIS_Text.hxx>
/**
* Drawer for bitmap text object
* @ingroup nis_library
*/
class NIS_TextDrawer : public NIS_Drawer
{
public:
// ---------- PUBLIC METHODS ----------
class DrawList : public NIS_DrawList
{
protected:
inline DrawList(const Handle_NIS_View& theView)
: NIS_DrawList (theView), IsFontUpdated(Standard_True) {}
//! Find an empty range of list IDs and allocate it.
Standard_EXPORT void SetListID (const NIS_Drawer::DrawType theType,
const Standard_Size nLists);
Standard_Boolean IsFontUpdated;
friend class NIS_TextDrawer;
};
/**
* Empty constructor.
*/
Standard_EXPORT NIS_TextDrawer ();
/**
* Special implementation - create DrawList for this object.
*/
Standard_EXPORT virtual NIS_DrawList*
createDefaultList (const Handle_NIS_View& theView) const;
/**
* Copy the relevant information from another instance of Drawer.
* raises exception if theOther has incompatible type (test IsKind).
*/
Standard_EXPORT virtual void Assign (const Handle_NIS_Drawer& theOther);
/**
* Matching two instances, for Map interface.
*/
Standard_EXPORT virtual Standard_Boolean
IsEqual (const Handle_NIS_Drawer& theOth)const;
/**
* Called before execution of Draw(), once per group of interactive objects.
*/
Standard_EXPORT virtual void BeforeDraw(const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Main function: display the given interactive object in the given view.
*/
Standard_EXPORT virtual void Draw (const Handle_NIS_InteractiveObject&,
const DrawType theType,
const NIS_DrawList& theDrawList);
/**
* Called after execution of Draw(), once per group of interactive objects.
*/
Standard_EXPORT virtual void AfterDraw(const DrawType theType,
const NIS_DrawList& theDrawList);
protected:
// ---------- PROTECTED METHODS ----------
Standard_EXPORT void SetFontUpdated () const;
private:
void updateFontBitmaps(DrawList& theList);
private:
// ---------- PRIVATE FIELDS ----------
NIS_Text::FontFamily myFontFamily;
NIS_Text::FontWeight myFontWeight;
NIS_Text::FontCharset myFontCharset;
Standard_Integer myFontHeight;
Standard_Integer myFontAngle; //!< in tenths of degree
Standard_Boolean myIsItalic;
Standard_Boolean myIsUnderline;
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_TextDrawer)
friend class NIS_Text;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_TextDrawer, NIS_Drawer)
#endif

110
src/NIS/NIS_Tools.cxx Normal file
View File

@@ -0,0 +1,110 @@
// File: NIS_Tools.cxx
// Created: 29.07.11 08:46
// Copyright: Open Cascade 2011
#include <NIS_Tools.hxx>
#include <NIS_Triangulated.hxx>
#include <NIS_InteractiveContext.hxx>
#include <NIS_Point.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS.hxx>
#include <Poly_Triangulation.hxx>
#include <BRep_Tool.hxx>
//=======================================================================
//function : Decompose
//purpose : Function for creating the Local selection
//=======================================================================
Standard_Boolean NIS_Tools::Decompose
(const TopoDS_Shape& theSh,
const Standard_Real theToler,
const Standard_Integer theTypes,
const Handle(NIS_InteractiveContext)& theCtx,
TopTools_DataMapOfIntegerShape& theMap,
const Quantity_Color& theColor,
const NIS_Surface::DisplayMode theHlgMode,
const Standard_Real theLineWidth)
{
Standard_Boolean aRes = Standard_False;
if (theCtx.IsNull() || theSh.IsNull())
return aRes;
if (theTypes & Type_None)
return aRes;
TopTools_MapOfShape shMap;
if (theTypes & Type_Face)
{
TopExp_Explorer fexp (theSh, TopAbs_FACE);
for (; fexp.More(); fexp.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
if (!shMap.Add(aFace))
continue;
Standard_Real aToler = theToler;
TopLoc_Location aLoc;
Handle(Poly_Triangulation) aPolyTri = BRep_Tool::Triangulation(aFace, aLoc);
if (aPolyTri.IsNull() == Standard_False)
{
if (aPolyTri->Deflection() > theToler)
{
aToler = aPolyTri->Deflection();
}
}
Handle(NIS_Surface) aSurface = new NIS_Surface(aFace, aToler);
theCtx->Display(aSurface);
aSurface->SetHilightDisplayMode(theHlgMode);
aSurface->SetColor(theColor);
aSurface->SetBackColor(theColor);
if (!theMap.IsBound(aSurface->ID()))
theMap.Bind(aSurface->ID(), aFace);
}
}
if (theTypes & Type_Edge)
{
TopExp_Explorer eexp (theSh, TopAbs_EDGE);
for (; eexp.More(); eexp.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
if (!shMap.Add(anEdge))
continue;
Handle(NIS_Triangulated) aTri = new NIS_Triangulated(anEdge, theToler);
theCtx->Display(aTri);
if (!theMap.IsBound(aTri->ID()))
theMap.Bind(aTri->ID(), anEdge);
aTri->SetColor(theColor);
aTri->SetLineWidth(theLineWidth);
}
}
if (theTypes & Type_Vertex)
{
TopExp_Explorer vexp (theSh, TopAbs_VERTEX);
for (; vexp.More(); vexp.Next())
{
const TopoDS_Vertex& aVertex = TopoDS::Vertex(vexp.Current());
if (!shMap.Add(aVertex))
continue;
Handle(NIS_Point) aPoint = new NIS_Point(BRep_Tool::Pnt(aVertex).XYZ());
theCtx->Display(aPoint);
if (!theMap.IsBound(aPoint->ID()))
theMap.Bind(aPoint->ID(), aVertex);
aPoint->SetColor(theColor);
aPoint->SetMarkerType(NIS_MT_CIRCLE);
}
}
return !theMap.IsEmpty();
}

77
src/NIS/NIS_Tools.hxx Normal file
View File

@@ -0,0 +1,77 @@
// File: NIS_Tools.hxx
// Created: 09.07.11 23:47
// Copyright: Open Cascade 2011
#ifndef NIS_Tools_HeaderFile
#define NIS_Tools_HeaderFile
#include <NIS_Surface.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_DataMapOfIntegerShape.hxx>
template <class A> class NCollection_List;
class Handle_NIS_InteractiveContext;
/**
* class NIS_Tools
* Auxiliary algoritms and tools.
*/
class NIS_Tools
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Enumerated types of object for local selection
*/
enum DecomposeType {
Type_None = 0x001,
Type_Face = 0x002,
Type_Edge = 0x004,
Type_Vertex = 0x008
};
struct PresentableShape {
TopoDS_Shape Shape;
Standard_Integer PresentationID;
};
/**
* Function for creating the Local selection.
* Update of viewer should be called by GUI layer. This is done for
* performance reasons to have one update per all the operations.
* @param theShape
* Original shape to be decomposed.
* @param theToler
* Tolerance for triangulation/tessellation of subshapes.
* @param theTypes
* Combination of bits, defined in enum DecomposeType.
* @param theCtx
* The context where all created objects will be displayed.
* @param theMap
* map of shapes
* @param theColor
* Color for displaing of new IO in Normal mode
* @param theHlgMode
* Set the hilight display mode for surface(Shading or Wirefram)
* The default mode is Shading
* @returns
* the list of ID of new presentations (NIS_Surface for Faces and
* NIS_Triangulated for edges).
* If theCtx is NULL then returns an empty list and false.
*/
Standard_EXPORT static Standard_Boolean Decompose
(const TopoDS_Shape& theShape,
const Standard_Real theToler,
const Standard_Integer theTypes,
const Handle_NIS_InteractiveContext& theCtx,
TopTools_DataMapOfIntegerShape& theMap,
const Quantity_Color& theColor,
const NIS_Surface::DisplayMode theHlgMode = NIS_Surface::Shading,
const Standard_Real theLineWidth = 1.f);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -17,12 +17,13 @@
#define NIS_Triangulated_HeaderFile
#include <NIS_InteractiveObject.hxx>
#include <Quantity_Color.hxx>
#include <NIS_IndexLists.hxx>
class Handle_NIS_TriangulatedDrawer;
class NCollection_BaseAllocator;
class Handle_NCollection_BaseAllocator;
class NIS_TriangulatedDrawer;
class TopoDS_Shape;
/**
* Interactive object that consists of triangles, lines and polygons without
@@ -45,6 +46,7 @@ class NIS_TriangulatedDrawer;
* constructor or in any Set* method. For example, if this number of nodes is
* smaller than 256 then 8-bit representation is selected. The choice is stored
* in 'myIndexType' data member.
* @ingroup nis_library
*/
class NIS_Triangulated : public NIS_InteractiveObject
@@ -66,7 +68,7 @@ class NIS_Triangulated : public NIS_InteractiveObject
public:
/**
* Enumerated type of polygon rendering.
* Enumerated type of polygon rendering
*/
enum PolygonType {
Polygon_Default = 0, //!< Polygon as LINE, Triangulation as FILL
@@ -74,6 +76,30 @@ class NIS_Triangulated : public NIS_InteractiveObject
Polygon_Fill = 2 //!< Both Polygon and Triangulation as FILL
};
/**
* Specifies what kind of primitives to render
*/
enum TriMode {
/**
* Treats each triplet of vertices as an independent triangle.
* Vertices 3n2, 3n1, and 3n define triangle n. n/3 triangles are drawn.
*/
TriMode_Triangles = 0,
/**
* Draws a connected group of triangles. One triangle is defined for each
* vertex presented after the first two vertices. n+2 triangles are drawn.
* For odd n, vertices n, n+1, and n+2 define triangle n.
* For even n, vertices n+1, n, and n+2 define triangle n.
*/
TriMode_Triangle_Strip = 1,
/**
* Draws a connected group of triangles. One triangle is defined for each
* vertex presented after the first two vertices. n+2 triangles are drawn.
* Vertices 1, n+1, and n+2 define triangle n.
*/
TriMode_Triangle_Fan = 2
};
public:
// ---------- PUBLIC METHODS ----------
@@ -95,6 +121,29 @@ class NIS_Triangulated : public NIS_InteractiveObject
const Handle_NCollection_BaseAllocator&
theAlloc = 0L);
/**
* Constructor. Create a presentation for edges from a given shape.
* Used for local selection
* @param theEdges
* Get the list of edges from the given shape for presentation.
* @param theDeflection
* Deflection for descretizing 'theEdges'.
* @param theAlloc
* Allocator for internal data
*/
Standard_EXPORT NIS_Triangulated(const TopoDS_Shape& theEdges,
const Standard_Real theDeflection,
const Handle_NCollection_BaseAllocator&
theAlloc = 0L);
/**
* Initialize the instance with a TopoDS_Shape. Used in constructor but can
* be called any time to redefine the geometry.
*/
Standard_EXPORT void Init (const TopoDS_Shape& theShape,
const Standard_Real theDefl,
const Standard_Real theAngularDefl = 0.1);
/**
* Define the polygonal presentration.
* @param nPolygons
@@ -119,6 +168,18 @@ class NIS_Triangulated : public NIS_InteractiveObject
(const Standard_Integer nTriangles,
const Standard_Integer nNodes = 0);
/**
* Define the triangulated fan presentration.
* @param nFans
* Number of fans. If set to 0, fan triangulation is cancelled
* @param nNodes
* Optional: Number of nodes to allocate. If left as 0, the previous nodes
* allocation is used, otherwise a new allocation is created.
*/
Standard_EXPORT void SetTriangulationFanPrs
(const Standard_Integer nFans,
const Standard_Integer nNodes = 0);
/**
* Define the line presentration (polygon through points)
* @param nPoints
@@ -171,6 +232,12 @@ class NIS_Triangulated : public NIS_InteractiveObject
inline Standard_Boolean IsSegments () const
{ return (myType & Type_Segments) != 0; }
/**
* Query if there is fan triangulation component in the presentation.
*/
inline Standard_Boolean IsFanTriangulation () const
{ return (IsTriangulation() && (myTriMode == TriMode_Triangle_Fan)); }
/**
* Reset all data memebers and free all allocated memory.
* Called from the destructor, also can be usedto re-initialize a given
@@ -209,6 +276,14 @@ class NIS_Triangulated : public NIS_InteractiveObject
const Standard_Integer iNode1,
const Standard_Integer iNode2);
/**
* Define the fan triangles list.
*/
Standard_EXPORT void SetFanTriangles(const Standard_Integer ind,
const Standard_Integer nbTris,
const Standard_Integer startNodeIdx,
const int* triList);
/**
* Allocate a single polygon, should be called for each polygon following
* the call SetPolygonsPrs(). The polygon can be filled by node indices using
@@ -239,18 +314,24 @@ class NIS_Triangulated : public NIS_InteractiveObject
inline Standard_Integer NTriangles() const
{ return myNTriangles; }
/**
* Query the number of lines.
*/
inline Standard_Integer NLines() const
{ return myLines.NArrays(); }
/**
* Query the number of line points.
*/
inline Standard_Integer NLineNodes() const
{ return myNLineNodes; }
inline Standard_Integer NLineNodes(const Standard_Integer indLine = 0) const
{ return (myLines.NArrays() == 0) ? 0 : myLines.NArrayIndexes(indLine); }
/**
* Query the number of polygons.
*/
inline Standard_Integer NPolygons () const
{ return static_cast<Standard_Integer>(myNPolygons); }
{ return myPolygons.NArrays(); }
/**
* Query the node by its index.
* @return
@@ -259,6 +340,18 @@ class NIS_Triangulated : public NIS_InteractiveObject
inline const Standard_ShortReal * Node (const Standard_Integer ind) const
{ return &mypNodes[ind * myNodeCoord]; }
/**
* Query the coordinates number (2 or 3 coordinates).
*/
inline Standard_Integer NodeCoord () const
{ return myNodeCoord; }
/**
* Query the number of fan Triangles in List.
*/
Standard_EXPORT Standard_Integer NFanInList (const Standard_Integer ind) const;
/**
* Define the node of a polygon by index.
* @param indPoly
@@ -303,35 +396,6 @@ class NIS_Triangulated : public NIS_InteractiveObject
Standard_EXPORT void SetPolygonType
(const PolygonType theType);
/**
* Set the normal color for presentation.
* @param theColor
* New color to use for the presentation.
*/
Standard_EXPORT void SetColor (const Quantity_Color& theColor);
/**
* Get Normal, Transparent or Hilighted color of the presentation.
* @param theDrawType
* The draw type, for which the color is retrieved.
*/
Standard_EXPORT Quantity_Color GetColor
(const NIS_Drawer::DrawType theDrawType) const;
/**
* Set the color for hilighted presentation.
* @param theColor
* New color to use for the presentation.
*/
Standard_EXPORT void SetHilightColor (const Quantity_Color& theColor);
/**
* Set the color for dynamic hilight presentation.
* @param theColor
* New color to use for the presentation.
*/
Standard_EXPORT void SetDynHilightColor(const Quantity_Color& theColor);
/**
* Set the width of line presentations in pixels.
* @param theWidth
@@ -339,6 +403,19 @@ class NIS_Triangulated : public NIS_InteractiveObject
*/
Standard_EXPORT void SetLineWidth (const Standard_Real theWidth);
/**
* Get the width of line presentation in pixels.
*/
Standard_EXPORT Standard_Real GetLineWidth () const;
/**
* Set the line style.
* @param theStyle
* Line style to be used for the presentation.
* 16-bit integer is passed as glLineStipple(1, theStyle)
*/
Standard_EXPORT void SetLineStyle (const Standard_Integer theStyle);
/**
* Create a copy of theObject except its ID.
* @param theAll
@@ -410,6 +487,7 @@ class NIS_Triangulated : public NIS_InteractiveObject
Standard_EXPORT static int tri2d_line_intersect(const double start[3],
const double dir[3],
const double over2,
const float V0[2],
const float V1[2],
const float V2[2],
@@ -468,14 +546,14 @@ class NIS_Triangulated : public NIS_InteractiveObject
*/
Standard_EXPORT virtual void Delete () const;
protected:
/**
* Allocator-based operator new for dynamic allocations in method Clone()
*/
DEFINE_STANDARD_ALLOC
DEFINE_NCOLLECTION_ALLOC
protected:
/**
* Create a 3D bounding box of the object.
*/
@@ -499,6 +577,19 @@ class NIS_Triangulated : public NIS_InteractiveObject
Standard_EXPORT float* nodeArrAtInd (const Standard_Integer * theArr,
const Standard_Integer i) const;
/**
* Auxiulary function computing of intersection with lines.
* This function is used in "intersect" functions.
*/
Standard_EXPORT Standard_Boolean
intersectArray (const Standard_Integer* theArray,
const Standard_Integer theNNodes,
const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean isFullIn,
const Standard_Integer theIncremIdx = 1) const;
protected:
// ---------- PROTECTED FIELDS ----------
@@ -506,17 +597,17 @@ class NIS_Triangulated : public NIS_InteractiveObject
Standard_Integer myType; //!< Combination of Type_* constants
Standard_ShortReal * mypNodes;
Standard_Integer * mypTriangles;
Standard_Integer * mypLines;
Standard_Integer ** mypPolygons;
NIS_IndexLists myLines;
NIS_IndexLists myPolygons;
NIS_IndexLists myFans;
Standard_Integer myNNodes;
Standard_Integer myNTriangles;
Standard_Integer myNLineNodes;
unsigned int myNPolygons : 24;
Standard_Integer myNTriangles;
Standard_Boolean myIsDrawPolygons : 1;
Standard_Boolean myIsCloned : 1; //!< How it is allocated
unsigned int myIndexType : 2; //!< 0:8bit, 1:16bit, 2:32bit
unsigned int myNodeCoord : 2; //!< 2 or 3 coordinates
unsigned int myPolygonType : 2;
unsigned int myTriMode : 2;
public:
// Declaration of CASCADE RTTI

View File

@@ -14,7 +14,6 @@
// commercial license or contractual agreement.
#include <NIS_TriangulatedDrawer.hxx>
#include <NIS_InteractiveObject.hxx>
#include <NIS_Triangulated.hxx>
#ifdef _DEBUG
#include <Standard_ProgramError.hxx>
@@ -44,16 +43,14 @@ NIS_TriangulatedDrawer::NIS_TriangulatedDrawer
(const Quantity_Color theNormal,
const Quantity_Color theHilight,
const Quantity_Color theDynHilight)
: myPolygonAsLineLoop (Standard_False),
myLineWidth (1.f),
myIsDrawPolygons (Standard_False),
myPolygonType (NIS_Triangulated::Polygon_Default)
: NIS_Drawer (theHilight, theDynHilight),
myPolygonAsLineLoop (Standard_False),
myLineWidth (1.f),
myLineType (0),
myIsDrawPolygons (Standard_False),
myPolygonType (NIS_Triangulated::Polygon_Default)
{
myColor[Draw_Normal] = theNormal;
myColor[Draw_Top] = theNormal;
myColor[Draw_Transparent] = theNormal;
myColor[Draw_Hilighted] = theHilight;
myColor[Draw_DynHilighted] = theDynHilight;
SetColor(Draw_Normal, theNormal);
}
//=======================================================================
@@ -67,12 +64,8 @@ void NIS_TriangulatedDrawer::Assign (const Handle_NIS_Drawer& theOther)
NIS_Drawer::Assign (theOther);
const Handle(NIS_TriangulatedDrawer)& anOther =
static_cast <const Handle(NIS_TriangulatedDrawer)&> (theOther);
myColor[Draw_Normal] = anOther->myColor[Draw_Normal];
myColor[Draw_Top] = anOther->myColor[Draw_Top];
myColor[Draw_Transparent] = anOther->myColor[Draw_Transparent];
myColor[Draw_Hilighted] = anOther->myColor[Draw_Hilighted];
myColor[Draw_DynHilighted] = anOther->myColor[Draw_DynHilighted];
myLineWidth = anOther->myLineWidth;
myLineType = anOther->myLineType;
myIsDrawPolygons = anOther->myIsDrawPolygons;
myPolygonType = anOther->myPolygonType;
}
@@ -93,14 +86,9 @@ Standard_Boolean NIS_TriangulatedDrawer::IsEqual
const Handle(NIS_TriangulatedDrawer) anOther =
Handle(NIS_TriangulatedDrawer)::DownCast (theOther);
if (NIS_Drawer::IsEqual(theOther))
aResult = (anOther->myColor[Draw_Normal]
.SquareDistance (myColor[Draw_Normal]) < anEpsilon2 &&
anOther->myColor[Draw_Hilighted]
.SquareDistance (myColor[Draw_Hilighted]) < anEpsilon2 &&
anOther->myColor[Draw_DynHilighted]
.SquareDistance (myColor[Draw_DynHilighted]) < anEpsilon2 &&
(anOther->myLineWidth - myLineWidth) *
aResult = ((anOther->myLineWidth - myLineWidth) *
(anOther->myLineWidth - myLineWidth) < 0.01 &&
anOther->myLineType == myLineType &&
anOther->myIsDrawPolygons == myIsDrawPolygons &&
anOther->myPolygonType == myPolygonType);
return aResult;
@@ -144,7 +132,7 @@ void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
anOffsetHilighted = 1;
#endif
}
myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
GetColor(theType).Values (aValue[0], aValue[1], aValue[2], bidTC);
glColor3d (aValue[0], aValue[1], aValue[2]);
break;
case Draw_Normal:
@@ -153,7 +141,7 @@ void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
#ifndef NEGATIVE_POFFSET
anOffsetHilighted = 11;
#endif
myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
GetColor(theType).Values (aValue[0], aValue[1], aValue[2], bidTC);
aValue[3] = 1. - myTransparency;
if (myTransparency > 0.01) {
glEnable(GL_BLEND);
@@ -182,6 +170,11 @@ void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
}
glEnableClientState (GL_VERTEX_ARRAY);
glLineWidth (aLineWidth);
if (myLineType > 0)
{
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, (GLushort)myLineType);
}
glShadeModel(GL_FLAT);
glDisable(GL_LIGHTING);
}
@@ -219,6 +212,11 @@ void NIS_TriangulatedDrawer::AfterDraw (const DrawType theType,
if (myPolygonType == NIS_Triangulated::Polygon_Line ||
(myPolygonType == NIS_Triangulated::Polygon_Default && myIsDrawPolygons))
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
if (myLineType > 0)
{
glDisable(GL_LINE_STIPPLE);
}
}
//=======================================================================
@@ -249,8 +247,19 @@ void NIS_TriangulatedDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
if (myIsDrawPolygons == Standard_False) {
if (pObject->IsTriangulation()) {
glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
aType, pObject->mypTriangles);
if (pObject->IsFanTriangulation()) {
Standard_Integer i;
for (i = 0; i < pObject->myFans.NArrays(); i++)
{
Standard_Integer nbFanTri = pObject->NFanInList(i);
if (nbFanTri > 0)
glDrawElements(GL_TRIANGLE_FAN, nbFanTri,
aType, pObject->myFans.ArrayIndexes(i));
}
}
if (pObject->NTriangles() > 0)
glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
aType, pObject->mypTriangles);
}
} else {
if (pObject->IsPolygons()) {
@@ -263,35 +272,26 @@ void NIS_TriangulatedDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
const Standard_Integer nPoly = pObject->NPolygons();
for (Standard_Integer i = 0; i < nPoly; i++) {
const Standard_Integer nSize = pObject->NPolygonNodes(i);
void* anArray;
if (pObject->myIndexType == 0)
anArray = reinterpret_cast<unsigned char *>(pObject->mypPolygons[i]) + 1;
else if (pObject->myIndexType == 1)
anArray = reinterpret_cast<unsigned short *>(pObject->mypPolygons[i]) + 1;
else
anArray = pObject->mypPolygons[i] + 1;
glDrawElements (aMode, nSize, aType, anArray);
glDrawElements (aMode, nSize, aType,
pObject->myPolygons.ArrayIndexes(i));
}
}
}
if (pObject->IsSegments())
glDrawElements (GL_LINES, pObject->NLineNodes(),
aType, pObject->mypLines);
if (pObject->IsSegments() && pObject->NLineNodes() > 0) {
glDrawElements (GL_LINES, pObject->NLineNodes(0),
aType, pObject->myLines.ArrayIndexes(0));
}
else {
Standard_Boolean isLoop;
if (pObject->IsLine(isLoop))
{
if (isLoop) {
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glDrawElements (GL_LINE_LOOP, pObject->NLineNodes(),
aType, pObject->mypLines);
// glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
} else {
glDrawElements (GL_LINE_STRIP, pObject->NLineNodes(),
aType, pObject->mypLines);
const GLenum lineType = (isLoop ? GL_LINE_LOOP : GL_LINE_STRIP);
const Standard_Integer nLine = pObject->NLines();
for (Standard_Integer i = 0; i < nLine; i++) {
const Standard_Integer nSize = pObject->NLineNodes(i);
glDrawElements (lineType, nSize,
aType, pObject->myLines.ArrayIndexes(i));
}
}
}
}

View File

@@ -23,6 +23,7 @@ class NIS_Triangulated;
/**
* Drawer for interactive object type NIS_Triangulated.
* @ingroup nis_library
*/
class NIS_TriangulatedDrawer : public NIS_Drawer
@@ -79,8 +80,8 @@ protected:
*/
Standard_Boolean myPolygonAsLineLoop;
Quantity_Color myColor[5];
Standard_ShortReal myLineWidth;
Standard_Integer myLineType;
Standard_Boolean myIsDrawPolygons;
unsigned int myPolygonType;

View File

@@ -13,6 +13,9 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <OpenGl_GlCore11.hxx>
#include <OpenGl_Context.hxx>
#include <NIS_View.hxx>
#include <NIS_InteractiveContext.hxx>
#include <NIS_InteractiveObject.hxx>
@@ -25,6 +28,8 @@
IMPLEMENT_STANDARD_HANDLE (NIS_View, V3d_OrthographicView)
IMPLEMENT_STANDARD_RTTIEXT (NIS_View, V3d_OrthographicView)
IMPLEMENT_STANDARD_HANDLE (NIS_ViewData, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT (NIS_ViewData, Standard_Transient)
//=======================================================================
//function : NIS_View()
@@ -34,11 +39,21 @@ IMPLEMENT_STANDARD_RTTIEXT (NIS_View, V3d_OrthographicView)
NIS_View::NIS_View (const Handle(V3d_Viewer)& theViewer,
const Handle(Aspect_Window)& theWindow)
: V3d_OrthographicView (theViewer),
myIsTopHilight(Standard_False),
myDoHilightSelected(Standard_True)
myIsTopHilight (Standard_False),
myIsTopDynHilight (Standard_False),
myDoHilightSelected (Standard_True),
myGlCtx (NULL),
myHDC (0L),
myHGLRC (0L)
{
if (!theWindow.IsNull())
if (!theWindow.IsNull()) {
myViewport[0] = -1;
V3d_View::SetWindow (theWindow, NULL, &MyCallback, this);
}
myViewport[0] = 0;
myViewport[1] = 0;
myViewport[2] = 0;
myViewport[3] = 0;
}
//=======================================================================
@@ -48,7 +63,11 @@ NIS_View::NIS_View (const Handle(V3d_Viewer)& theViewer,
void NIS_View::SetWindow(const Handle(Aspect_Window) &theWindow)
{
myViewport[0] = -1;
V3d_View::SetWindow (theWindow, NULL, &MyCallback, this);
myViewport[0] = 0;
myHDC = 0L;
myHGLRC = 0L;
}
// //=======================================================================
@@ -90,11 +109,17 @@ void NIS_View::RemoveContext (NIS_InteractiveContext * theCtx)
break;
}
// If draw lists are shared in this Context then they should be
// destroyed when we detach from the last view (1 remaining view is detached).
Standard_Boolean isForcedDestroy(Standard_False);
if (theCtx->myIsShareDrawList && theCtx->myViews.Extent() == 1)
isForcedDestroy = Standard_True;
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (theCtx->GetDrawers ());
for (; anIterD.More(); anIterD.Next()) {
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
if (aDrawer.IsNull() == Standard_False) {
aDrawer->UpdateExListId(this);
aDrawer->UpdateExListId(isForcedDestroy ? 0L : this);
}
}
}
@@ -185,6 +210,46 @@ Standard_Boolean NIS_View::FitAll3d (const Quantity_Coefficient theCoef)
return aResult;
}
//=======================================================================
//function : GetViewData
//purpose : get or create a new ViewData instance.
// For thread safety the instances are kept in a list instead of
// map: operation List::Append is atomic thus safe.
//=======================================================================
Handle_NIS_ViewData& NIS_View::GetViewData (const char * theKey)
{
NCollection_List<struct NamedViewData>::Iterator anIter(myViewData);
for (; anIter.More(); anIter.Next()) {
const NamedViewData& aData = anIter.Value();
if (aData.Name.IsEqual(theKey))
break;
}
if (anIter.More())
return anIter.ChangeValue().Data;
struct NamedViewData aNewData;
aNewData.Name = theKey;
return myViewData.Append(aNewData).Data;
}
//=======================================================================
//function : Remove
//purpose : Expressly close internal data structures
//=======================================================================
void NIS_View::Remove ()
{
if (!myGlCtx.IsNull())
{
if (myGlCtx->MakeCurrent())
{
myGlCtx.Nullify();
myViewData.Clear();
}
}
V3d_View::Remove();
}
//=======================================================================
//function : GetBndBox
//purpose :
@@ -262,42 +327,141 @@ void NIS_View::GetBndBox( Standard_Integer& theXMin, Standard_Integer& theXMax,
}
}
//=======================================================================
//function : MakeCurrent
//purpose :
//=======================================================================
Standard_Boolean NIS_View::MakeCurrent() const
{
Standard_Boolean aResult(Standard_False);
HDC anActiveHdc = wglGetCurrentDC();
HGLRC anActiveGlCtx = wglGetCurrentContext();
if (myHDC == anActiveHdc && myHGLRC == anActiveGlCtx)
aResult = Standard_True;
else if (wglMakeCurrent(reinterpret_cast<HDC>(myHDC),
reinterpret_cast<HGLRC>(myHGLRC)))
aResult = Standard_True;
return aResult;
}
//=======================================================================
//function : MyCallback
//purpose :
//=======================================================================
int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
void* theUserData,
Aspect_GraphicCallbackStruct* thecallData)
{
// NKV 14.07.11: Avoid double rendering of the scene
// (workaround of integration from BUG OCC22377, that calls view
// call back twice: before drawing overlay layer and after drawing,
// see comments to OCC_PRE_OVERLAY definition)
NIS_View* thisView = static_cast<NIS_View*> (theUserData);
if ((thecallData->reason & OCC_PRE_OVERLAY) == 0) {
Handle(OpenGl_Context) aGlContext =
Handle(OpenGl_Context)::DownCast(thecallData->glContext);
thisView->myGlCtx = aGlContext;
if (!thisView->myHDC)
thisView->myHDC = wglGetCurrentDC();
if (!thisView->myHGLRC)
thisView->myHGLRC = wglGetCurrentContext();
if (thisView->myViewport[0] >= 0) {
thisView->redrawCallback();
}
}
return 0;
}
//=======================================================================
//function : redrawCallback
//purpose :
//=======================================================================
int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
void* ptrData,
Aspect_GraphicCallbackStruct* callData /* call data */)
void NIS_View::redrawCallback()
{
// Avoid multiple rendering of the scene ( accordingly with update of
// callback mechanism, that invokes additional callbacks before
// underlay and overlay redrawing with OCC_PRE_REDRAW and OCC_PRE_OVERLAY
// bits added to the "reason" value of the callback data structure;
// see comments to OCC_REDRAW_ADDITIONAL_CALLBACKS definition )
if (callData->reason & OCC_REDRAW_ADDITIONAL_CALLBACKS)
return 0;
// cache render mode state
GLint aRendMode = GL_RENDER;
glGetIntegerv (GL_RENDER_MODE, &aRendMode);
if (myGlCtx.IsNull() == Standard_False) {
myGlCtx->Init();
myGlCtx->SetFeedback (aRendMode == GL_FEEDBACK);
}
const Handle(NIS_View) thisView = this;
// ==== Get pixel size
{
glGetIntegerv(GL_VIEWPORT, myViewport);
Standard_Integer anX(myViewport[0] + myViewport[2]/2);
Standard_Integer anY(myViewport[1] + myViewport[3]/2);
const gp_XYZ aPnt[3] = {
UnConvert (anX, anY),
UnConvert (anX + 5, anY),
UnConvert (anX, anY + 5)
};
myPixelSize.SetCoord(0.2 * (aPnt[1] - aPnt[0]).Modulus(),
0.2 * (aPnt[2] - aPnt[0]).Modulus());
}
// ==== Get view transformation
{
Standard_Real anX, anY, aZ;
// vector orthogonal to the view plane
Proj (anX, anY, aZ);
myProj.SetCoord (anX, anY, aZ);
// 3D point for the 3D coordinates
Convert(myViewport[0] + myViewport[2] / 2,
myViewport[1] + myViewport[3] / 2, anX, anY, aZ);
const gp_Pnt anEye (anX, anY, aZ);
// 3D point for the 3D coordinates
Convert(myViewport[0] + myViewport[2],
myViewport[1] + myViewport[3] / 2, anX, anY, aZ);
const gp_XYZ anXdir (gp_XYZ(anX, anY, aZ) - anEye.XYZ());
myViewSize.SetX(anXdir.Modulus());
Convert(myViewport[0] + myViewport[2] / 2, myViewport[1], anX, anY, aZ);
myViewSize.SetY((gp_XYZ(anX, anY, aZ) - anEye.XYZ()).Modulus());
if (anXdir.SquareModulus() > 1e-20) {
const gp_Ax3 anAx3 (anEye, myProj, anXdir);
myTrsf.SetTransformation (anAx3);
}
}
// ==== Manage the ViewData
NCollection_List<NamedViewData>::Iterator anIterVD(myViewData);
for (; anIterVD.More(); anIterVD.Next()) {
const Handle(NIS_ViewData)& aData = anIterVD.Value().Data;
if (aData.IsNull() == Standard_False) {
aData->Init();
if (aData->myView != this)
aData->myView = this;
}
}
const Handle(NIS_View) thisView (static_cast<NIS_View *> (ptrData));
NCollection_List<NIS_InteractiveContext *>::Iterator anIter;
#ifdef CLIP
// Find the bounding box of all displayed objects by summing the boxes stored
// in the relevant DrawList instances.
Bnd_B3f aBndBox;
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
NCollection_List<NIS_InteractiveContext *>::Iterator anIter = myContexts;
for (; anIter.More(); anIter.Next())
{
anIter.Value()->GetBox (aBndBox, pView);
}
if (aBndBox.IsVoid() == Standard_False) {
const gp_XYZ aBoxSize = 0.5 * (aBndBox.CornerMax() - aBndBox.CornerMin());
const gp_XYZ aBoxCenter = 0.5 * (aBndBox.CornerMax() + aBndBox.CornerMin());
// Find the ray passing through the clicked point in the view window.
Standard_Real anX, anY, aZ;
thisView->Convert(0, 0, anX, anY, aZ); // 3D point for the 3D coordinates
Standard_Real aZ;
Convert(0, 0, anX, anY, aZ); // 3D point for the 3D coordinates
const gp_Pnt anEye (anX, anY, aZ);
thisView->Proj (anX, anY, aZ); // vector orthogonal to the view plane
Proj (anX, anY, aZ); // vector orthogonal to the view plane
const gp_Dir aProj (anX, anY, aZ);
const gp_Ax1 anAxis (anEye, aProj);
@@ -335,12 +499,13 @@ int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (!isDepthTest) {
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearDepth(1.);
glClear(GL_DEPTH_BUFFER_BIT);
}
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
TColStd_MapIteratorOfPackedMapOfInteger anIterM(thisView->myExListId);
TColStd_MapIteratorOfPackedMapOfInteger anIterM (myExListId);
for (; anIterM.More(); anIterM.Next())
if (anIterM.Key() != 0) {
#ifdef ARRAY_LISTS
@@ -349,33 +514,56 @@ int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
glDeleteLists (anIterM.Key(), 1);
}
#endif
thisView->myExListId.Clear();
myExListId.Clear();
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Normal);
redraw (thisView, NIS_Drawer::Draw_Normal);
// #818151 - selected object is hidden by covered unselected one
// display hilighted objects always above the rest ones
if (thisView->myIsTopHilight == Standard_True) {
if (myIsTopHilight == Standard_True) {
glDepthFunc(GL_ALWAYS);
}
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Hilighted);
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_DynHilighted);
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Transparent);
redraw (thisView, NIS_Drawer::Draw_Hilighted);
// Depth buffer should be read-only for transparent objects,
// the same for further types
glDepthMask(GL_FALSE);
redraw (thisView, NIS_Drawer::Draw_Transparent);
if (myIsTopDynHilight == Standard_False)
{
redraw (thisView, NIS_Drawer::Draw_DynHilighted);
}
// draw top objects always above
if (thisView->myIsTopHilight == Standard_False) {
if (myIsTopHilight == Standard_False)
{
glDepthFunc(GL_ALWAYS);
}
if (myIsTopDynHilight == Standard_True)
{
redraw (thisView, NIS_Drawer::Draw_DynHilighted);
}
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Top);
redraw (thisView, NIS_Drawer::Draw_Top);
}
return 0;
//=======================================================================
//function : redraw
//purpose :
//=======================================================================
void NIS_View::redraw (const Handle(NIS_View)& theView,
const NIS_Drawer::DrawType theType)
{
for (Standard_Integer aPriority = 0; aPriority < NIS_Drawer::Priority_LevelsNb; ++aPriority)
{
for (NCollection_List<NIS_InteractiveContext *>::Iterator anIter = myContexts;
anIter.More(); anIter.Next())
{
anIter.Value()->redraw (theView, theType, (NIS_Drawer::PriorityLevel )aPriority);
}
}
}
//=======================================================================
@@ -383,19 +571,24 @@ int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
//purpose :
//=======================================================================
void NIS_View::DynamicHilight (const Standard_Integer theX,
const Standard_Integer theY)
Standard_Boolean NIS_View::DynamicHilight (const Standard_Integer theX,
const Standard_Integer theY)
{
Standard_Boolean aResult(Standard_False);
myDetected.Clear();
const Handle(NIS_InteractiveObject) aSelected = Pick (theX, theY);
const Handle(NIS_InteractiveObject) aSelected =
Pick (theX, theY, NIS_SelectFilter::DynHilight);
// ASV: if at least one Context returns IsSelectable()==False,
// hilight is canceled, this method returns
if (aSelected.IsNull() == Standard_False) {
if (aSelected->IsSelectable() == Standard_False)
return;
}
if (aSelected != myDynHilighted) {
if ((aSelected.IsNull() == Standard_False &&
aSelected->IsSelectable() == Standard_False) ||
aSelected == myDynHilighted)
{
;//DrawDirect(theX, theY);
} else {
//DrawDirect(theX, theY, Standard_False);
const Handle(NIS_View) aView (this);
if (myDynHilighted.IsNull() == Standard_False)
if (myDynHilighted->GetDrawer().IsNull() == Standard_False)
@@ -415,7 +608,9 @@ void NIS_View::DynamicHilight (const Standard_Integer theX,
myDynHilighted = aSelected;
}
Redraw();
aResult = Standard_True;
}
return aResult;
}
//=======================================================================
@@ -425,7 +620,7 @@ void NIS_View::DynamicHilight (const Standard_Integer theX,
void NIS_View::DynamicUnhilight(const Handle_NIS_InteractiveObject& theObj)
{
if (theObj == myDynHilighted && theObj.IsNull() == Standard_False) {
if (theObj.IsNull() == Standard_False && theObj == myDynHilighted) {
const Handle(NIS_View) aView (this);
if (myDynHilighted->GetDrawer().IsNull() == Standard_False)
myDynHilighted->GetDrawer()->SetDynamicHilighted (Standard_False,
@@ -442,21 +637,32 @@ void NIS_View::DynamicUnhilight(const Handle_NIS_InteractiveObject& theObj)
void NIS_View::Select (const Standard_Integer theX,
const Standard_Integer theY,
const Standard_Boolean isForceMultiple,
const Standard_Boolean isModifierUsed,
const Standard_Boolean theRedraw)
{
myDetected.Clear();
const Handle(NIS_InteractiveObject) aSelected = Pick (theX, theY);
Standard_Real anOver;
const gp_Ax1 anAxis = PickAxis(theX, theY, anOver);
const Handle(NIS_InteractiveObject) aSelected =
Pick(anAxis, anOver, Standard_True, 0L, NIS_SelectFilter::Pick);
NCollection_List<NIS_InteractiveContext *>::Iterator anIter (myContexts);
for (; anIter.More(); anIter.Next())
anIter.Value()->ProcessSelection (aSelected, isForceMultiple);
Standard_Boolean isProcessed(Standard_False);
for (; anIter.More(); anIter.Next()) {
NIS_InteractiveContext* aCtx = anIter.Value();
if (aCtx != 0L)
if (aCtx->ProcessSelection (aSelected, isModifierUsed))
isProcessed = Standard_True;
}
if (aSelected == myDynHilighted && aSelected.IsNull() == Standard_False)
{
myDynHilighted.Nullify();
const Handle(NIS_Drawer)& aDrawer = aSelected->GetDrawer();
aDrawer->SetDynamicHilighted (Standard_False, aSelected, this);
isProcessed = Standard_True;
}
if (theRedraw) Redraw();
if (theRedraw && isProcessed)
Redraw();
}
//=======================================================================
@@ -468,7 +674,7 @@ void NIS_View::Select (const Standard_Integer theXmin,
const Standard_Integer theYmin,
const Standard_Integer theXmax,
const Standard_Integer theYmax,
const Standard_Boolean isForceMult,
const Standard_Boolean isModifierUsed,
const Standard_Boolean isFullyIncluded,
const Standard_Boolean theRedraw)
{
@@ -506,7 +712,7 @@ void NIS_View::Select (const Standard_Integer theXmin,
NIS_InteractiveContext * pCtx = anIterC.Value();
mapSelected.Clear();
pCtx->selectObjects (mapSelected, aBoxSel, aTrfInv, aTrf, isFullyIncluded);
pCtx->ProcessSelection (mapSelected, isForceMult);
pCtx->ProcessSelection (mapSelected, isModifierUsed);
}
if (theRedraw) Redraw();
}
@@ -517,12 +723,12 @@ void NIS_View::Select (const Standard_Integer theXmin,
//=======================================================================
void NIS_View::Select (const NCollection_List<gp_XY> &thePolygon,
const Standard_Boolean isForceMult,
const Standard_Boolean isModifierUsed,
const Standard_Boolean isFullyIncluded,
const Standard_Boolean theRedraw)
{
myDetected.Clear();
if (thePolygon.IsEmpty())
if (thePolygon.Extent() < 3)
return;
Standard_Real anX, anY, aZ;
@@ -578,32 +784,50 @@ void NIS_View::Select (const NCollection_List<gp_XY> &thePolygon,
NIS_InteractiveContext * pCtx = anIterC.Value();
mapSelected.Clear();
pCtx->selectObjects (mapSelected, aPoints, aPolyBox, aTrf, isFullyIncluded);
pCtx->ProcessSelection (mapSelected, isForceMult);
pCtx->ProcessSelection (mapSelected, isModifierUsed);
}
if (theRedraw) Redraw();
}
//=======================================================================
//function : Pick
//function : PickAxis
//purpose :
//=======================================================================
Handle_NIS_InteractiveObject NIS_View::Pick (const Standard_Integer theX,
const Standard_Integer theY)
gp_Ax1 NIS_View::PickAxis (const Standard_Integer theX,
const Standard_Integer theY,
Standard_Real& theOver)
{
// Find the ray passing through the clicked point in the view window.
Standard_Real anX, anY, aZ, anOver;
Standard_Real anX, anY, aZ;
Convert(theX, theY, anX, anY, aZ); // 3D point for the 3D coordinates
const gp_Pnt anEye (anX, anY, aZ);
#ifdef OBSOLETE
Proj (anX, anY, aZ); // vector orthogonal to the view plane
const gp_Dir aProj (-anX, -anY, -aZ);
const gp_Ax1 anAxis (anEye, aProj);
Convert (theX+1, theY+1, anX, anY, aZ);
anOver = ((gp_XYZ(anX, anY, aZ) - anEye.XYZ()) ^ aProj.XYZ()).Modulus() * 1.5;
theOver= ((gp_XYZ(anX, anY, aZ) - anEye.XYZ()) ^ aProj.XYZ()).Modulus() * 1.5;
#endif
theOver = 2 * myPixelSize.Modulus();
return gp_Ax1(anEye, -gp_Dir(myProj));
}
return Pick(anAxis, anOver, Standard_True);
//=======================================================================
//function : Pick
//purpose :
//=======================================================================
Handle_NIS_InteractiveObject NIS_View::Pick
(const Standard_Integer theX,
const Standard_Integer theY,
const NIS_SelectFilter::Event theEvent)
{
Standard_Real anOver;
const gp_Ax1 anAxis = PickAxis(theX, theY, anOver);
return Pick(anAxis, anOver, Standard_True, 0L, theEvent);
}
//=======================================================================
@@ -612,32 +836,101 @@ Handle_NIS_InteractiveObject NIS_View::Pick (const Standard_Integer theX,
//=======================================================================
Handle_NIS_InteractiveObject NIS_View::Pick
(const gp_Ax1& theAxis,
const Standard_Real theOver,
const Standard_Boolean isOnlySelectable)
(const gp_Ax1& theAxis,
const Standard_Real theOver,
const Standard_Boolean isOnlySelectable,
Standard_Real* theDistance,
const NIS_SelectFilter::Event theEvent)
{
typedef NCollection_List<NIS_InteractiveContext::DetectedEnt> LstDetected;
Standard_Real aDistance (0.1 * RealLast());
Handle(NIS_InteractiveObject) aSelected, aTmpSel;
LstDetected aDetected;
NCollection_List<NIS_InteractiveContext *>::Iterator anIterC (myContexts);
for (; anIterC.More(); anIterC.Next()) {
const Standard_Real aDist =
anIterC.Value()->selectObject (aTmpSel, aDetected, theAxis, theOver,
isOnlySelectable);
if (aDist < aDistance) {
aDistance = aDist;
aSelected = aTmpSel;
}
for (NCollection_List<NIS_InteractiveContext*>::Iterator anIterC (myContexts);
anIterC.More(); anIterC.Next())
{
anIterC.Value()->selectObject (aDetected, theAxis, theOver, isOnlySelectable, theEvent);
}
// simple iterating is enough to create list of detected objects
// in the order of increasing distance
myDetected.Clear();
for (LstDetected::Iterator anIt(aDetected); anIt.More(); anIt.Next())
myDetected.Append(anIt.Value().PObj);
for (LstDetected::Iterator anIt (aDetected); anIt.More(); anIt.Next())
{
myDetected.Append (anIt.Value().PObj);
}
Handle(NIS_InteractiveObject) aSelected = aDetected.IsEmpty() ? (NIS_InteractiveObject* )NULL : aDetected.First().PObj;
if (theDistance != NULL)
{
*theDistance = aDetected.IsEmpty() ? (0.1 * RealLast()) : aDetected.First().Dist;
}
if (aSelected.IsNull())
{
return aSelected;
}
// notify the SelectFilter if available
NIS_InteractiveContext* aSelectedCtx = aSelected->GetDrawer()->GetContext();
if (aSelectedCtx != NULL
&& !aSelectedCtx->GetFilter().IsNull()
&& aSelectedCtx->GetFilter()->ActsOn (aSelected->DynamicType()))
{
NIS_SelectFilter::Event aFinalEvent = NIS_SelectFilter::Indefinite;
if (theEvent == NIS_SelectFilter::Pick)
{
aFinalEvent = NIS_SelectFilter::Picked;
}
else if (theEvent == NIS_SelectFilter::DynHilight)
{
aFinalEvent = NIS_SelectFilter::DynHilighted;
}
aSelectedCtx->GetFilter()->IsOk (aSelected.operator->(), theAxis,
theOver, aFinalEvent);
}
return aSelected;
}
//=======================================================================
//function : UnConvert
//purpose : 2d pixel coord => 3d point coord in Ortho viewer
//=======================================================================
gp_XYZ NIS_View::UnConvert (const Standard_Integer theX,
const Standard_Integer theY) const
{
const Visual3d_ViewOrientation anOri = ViewOrientation();
Standard_Real anX, anY, aZ, anXp, anYp;
anOri.ViewReferencePoint().Coord(anX, anY, aZ);
gp_XYZ anOrigin(anX, anY, aZ);
anOri.ViewReferencePlane().Coord(anX, anY, aZ);
gp_XYZ aNorm(anX, anY, aZ);
anOri.ViewReferenceUp().Coord(anX, anY, aZ);
gp_XYZ anYdir(anX, anY, aZ);
gp_XYZ anXdir = anYdir ^ aNorm;
Convert(theX, theY, anXp, anYp);
return (anOrigin + anXdir * anXp + anYdir * anYp);
}
//=======================================================================
//function : ClipToViewport
//purpose : Test and clip the given coordinates to fit to the Viewport
//=======================================================================
Standard_Boolean NIS_View::ClipToViewport (Standard_Integer& theX,
Standard_Integer& theY) const
{
Standard_Integer iResult(0);
if (theX < myViewport[0])
theX = myViewport[0];
else if (theX >= myViewport[0] + myViewport[2])
theX = myViewport[0] + myViewport[2] - 1;
else
iResult |= 0x1;
if (theY < myViewport[1])
theY = myViewport[1];
else if (theY >= myViewport[1] + myViewport[3])
theY = myViewport[1] + myViewport[3] - 1;
else
iResult |= 0x2;
return iResult == 0x3;
}

View File

@@ -16,16 +16,22 @@
#ifndef NIS_View_HeaderFile
#define NIS_View_HeaderFile
#include <Handle_OpenGl_Context.hxx>
#include <Handle_NIS_InteractiveObject.hxx>
#include <V3d_OrthographicView.hxx>
#include <Standard_DefineHandle.hxx>
#include <Bnd_B3f.hxx>
#include <NCollection_List.hxx>
#include <NCollection_Vector.hxx>
#include <Bnd_B3f.hxx>
#include <NIS_Drawer.hxx>
#include <NIS_SelectFilter.hxx>
#include <NIS_ViewData.hxx>
#include <Standard_DefineHandle.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <V3d_OrthographicView.hxx>
#include <gp_XY.hxx>
class NIS_InteractiveContext;
class Handle_NIS_View;
class gp_Ax1;
/**
@@ -51,6 +57,7 @@ class gp_Ax1;
* </ul>
* The list of associated NIS_InteractiveContext can be modified by methods
* AddContext and RemoveContext.
* @ingroup nis_library
*/
class NIS_View : public V3d_OrthographicView
@@ -75,6 +82,12 @@ class NIS_View : public V3d_OrthographicView
*/
inline void SetHilightOnTop(const Standard_Boolean theTop = Standard_True)
{ myIsTopHilight = theTop; }
/**
* Indicate whether to draw dynamic hilighted objects on top of all other ones
*/
inline void SetDynHilightOnTop(const Standard_Boolean theTop = Standard_True)
{ myIsTopDynHilight = theTop; }
/**
* Indicate whether to hilight selected object dynamically
@@ -89,6 +102,12 @@ class NIS_View : public V3d_OrthographicView
theHilight = Standard_True)
{ myDoHilightSelected = theHilight; }
/**
* Gets indentifier whether a selected object should be dynamically highlighted
*/
inline Standard_Boolean GetDynHilightSelected () const
{ return myDoHilightSelected; }
/**
* Zoom the view to fit to visible objects size and positions.
* @param theCoef
@@ -101,6 +120,71 @@ class NIS_View : public V3d_OrthographicView
Standard_EXPORT Standard_Boolean FitAll3d (const Quantity_Coefficient theCoef
= 0.01);
/**
* Get the reference to GL context.
*/
inline const Handle_OpenGl_Context& GetGlContext() const
{ return myGlCtx; }
/**
* Get the reference to GL Data.
* @return
* Handle to ViewData for the unique value of theKey.
* If theKey is unknown, a ViewData handle is created and added to the Map
*/
Standard_EXPORT Handle_NIS_ViewData& GetViewData (const char * theKey);
/**
* Expressly close internal data structures, particularly OpenGl buffer
* objects, that may be hard to close in usual way, using destructor.
*/
Standard_EXPORT virtual void Remove ();
/**
* Query the size of 1 pixel in the middle, in X and Y directions.
*/
inline const gp_XY& GetPixelSize () const
{ return myPixelSize; }
/**
* Query the view size. X and Y directions components are half dimensions
* of the view box. To obtain the view box you can use:
* @code
* aViewBox.SetCenter(0., 0., 0.);
* aViewBox.SetHSize(aV->GetViewSize().X(), aV->GetViewSize().Y(), 10000.);
* @endcode
* The last parameter (10000) is arbitrary.
*/
inline const gp_XY& GetViewSize () const
{ return myViewSize; }
/**
* Get the viewport values as returned by GL_VIEWPORT OpenGl call.
* Normally, Index 0 and 1 - upper left corner, index 2 and 3 - width and
* height in pixels.
*/
inline Standard_Integer Viewport (const Standard_Integer i) const
{ return myViewport[i&3]; }
/**
* Check the input X, Y coordinates if they are outside the viewport and
* if they happen to be then correct to match.
* @return
* True if correction has been made
*/
Standard_EXPORT Standard_Boolean
ClipToViewport (Standard_Integer& theX,
Standard_Integer& theY) const;
/**
* Get view transformation. If you apply it to a real-space object then the
* object is moved to the coordinate system of the view box (see GetViewSize)
* that has its center in the middle of the view area and is oriented
* according to the current view matrix.
*/
inline const gp_Trsf& Transformation () const
{ return myTrsf; }
/**
* Gets bounding box covering objects displayed in viewer.
*/
@@ -123,8 +207,10 @@ class NIS_View : public V3d_OrthographicView
/**
* Set or unset the dynamically hilighted object, depending on the
* given mouse coordinates.
* @return True if hilighting/unhilighting takes place.
*/
Standard_EXPORT void DynamicHilight (const Standard_Integer theX,
Standard_EXPORT Standard_Boolean DynamicHilight
(const Standard_Integer theX,
const Standard_Integer theY);
/**
@@ -145,15 +231,15 @@ class NIS_View : public V3d_OrthographicView
* X coordinate of the view window
* @param theY
* X coordinate of the view window
* @param isForceMult
* True if the effect of multi-Selection should be forced (e.g., when Shift
* is pressed).
* @param isModifierUsed
* The selection modifier state. If the effect of multi-Selection should be
* forced in the Normal selection mode (the Shift is pressed).
* @param theRedraw
* True to redraw view automatically (default value).
*/
Standard_EXPORT void Select (const Standard_Integer theX,
const Standard_Integer theY,
const Standard_Boolean isForceMult
const Standard_Boolean isModifierUsed
= Standard_False,
const Standard_Boolean theRedraw
= Standard_True);
@@ -169,9 +255,9 @@ class NIS_View : public V3d_OrthographicView
* right X coordinate of the view window
* @param theYmax
* upper Y coordinate of the view window
* @param isForceMult
* True if the effect of multi-Selection should be forced (e.g., when Shift
* is pressed).
* @param isModifierUsed
* The selection modifier state. If the effect of multi-Selection should be
* forced in the Normal selection mode (the Shift is pressed).
* @param isFullyIncluded
* True if only those objects are processed that are fully inside the
* selection rectangle. False if objects fully or partially included in
@@ -183,7 +269,7 @@ class NIS_View : public V3d_OrthographicView
const Standard_Integer theYmin,
const Standard_Integer theXmax,
const Standard_Integer theYmax,
const Standard_Boolean isForceMult
const Standard_Boolean isModifierUsed
= Standard_False,
const Standard_Boolean isFullyIncluded
= Standard_False,
@@ -198,9 +284,9 @@ class NIS_View : public V3d_OrthographicView
* self-intersections. The last point should not coincide with the first
* point of the list. Points are interpreted as X and Y integer coordinates
* of the view window. Any two neighbor points should not be confused.
* @param isForceMult
* True if the effect of multi-Selection should be forced (e.g., when Shift
* is pressed).
* @param isModifierUsed
* The selection modifier state. If the effect of multi-Selection should be
* forced in the Normal selection mode (the Shift is pressed).
* @param isFullyIncluded
* True if only those objects are processed that are fully inside the
* selection rectangle. False if objects fully or partially included in
@@ -209,13 +295,28 @@ class NIS_View : public V3d_OrthographicView
* True to redraw view automatically (default value).
*/
Standard_EXPORT void Select (const NCollection_List<gp_XY> &thePolygon,
const Standard_Boolean isForceMult
const Standard_Boolean isModifierUsed
= Standard_False,
const Standard_Boolean isFullyIncluded
= Standard_False,
const Standard_Boolean theRedraw
= Standard_True);
/**
* Computation of 3D axis for objects selection
* @param theX
* X coordinate of mouse pointer in the window.
* @param theY
* Y coordinate of mouse pointer in the window.
* @param theOver
* Overlap for the returned 3D axis
* @return
* 3D axis for objects selection
*/
Standard_EXPORT gp_Ax1 PickAxis (const Standard_Integer theX,
const Standard_Integer theY,
Standard_Real& theOver);
/**
* Interactive selection by mouse click. Selection itself is performed in each
* Interactive Context attached to this View, accordingto the local parameters
@@ -224,17 +325,21 @@ class NIS_View : public V3d_OrthographicView
* X coordinate of mouse pointer in the window.
* @param theY
* Y coordinate of mouse pointer in the window.
* @param theEvent
* Event that invokes this method
* @return
* the selected object picked by the minimal intersection distance among
* all contexts attached to this View.
*/
Standard_EXPORT Handle_NIS_InteractiveObject
Pick (const Standard_Integer theX,
const Standard_Integer theY);
const Standard_Integer theY,
const NIS_SelectFilter::Event theEvent
= NIS_SelectFilter::Indefinite);
/**
* Interactive selection by mouse click. Selection itself is performed in each
* Interactive Context attached to this View, accordingto the local parameters
* Interactive Context attached to this View, according to the local parameters
* (mode, filter) of selection in each context.
* @param theAxis
* 3D axis for objects selection
@@ -243,6 +348,11 @@ class NIS_View : public V3d_OrthographicView
* @param isOnlySel
* If False, any displayed object can be picked, otherwise only selectable
* ones.
* @param pDistance
* Optional parameter, if defined then the shortest distance for picked
* object along the axis to projection point will be stored in it.
* @param theEvent
* Event that invokes this method
* @return
* the selected object picked by the minimal intersection distance among
* all contexts attached to this View.
@@ -250,7 +360,25 @@ class NIS_View : public V3d_OrthographicView
Standard_EXPORT Handle_NIS_InteractiveObject
Pick (const gp_Ax1& theAxis,
const Standard_Real theOver,
const Standard_Boolean isOnlySel);
const Standard_Boolean isOnlySel,
Standard_Real* pDistance = 0L,
const NIS_SelectFilter::Event theEvent
= NIS_SelectFilter::Indefinite);
/**
* Having pixel coordinates (X, Y starting from the top left corner) returns
* 3D coordinates of the corresponding point on view plane.
*/
Standard_EXPORT gp_XYZ UnConvert (const Standard_Integer theX,
const Standard_Integer theY) const;
/**
* Called outside the loop of refresing the view. Makes this OpenGl context
* current for the actual thread.
* @return False if failed.
*/
Standard_EXPORT Standard_Boolean
MakeCurrent () const;
/**
* Gets all objects detected by last call of Pick() method
@@ -264,6 +392,15 @@ class NIS_View : public V3d_OrthographicView
inline TColStd_PackedMapOfInteger& GetExListId ()
{ return myExListId; }
/**
* Get all contexts of view
*/
inline NCollection_List<NIS_InteractiveContext *> GetContexts () const
{ return myContexts; }
inline const Handle_NIS_InteractiveObject& GetDynHilighted() const
{ return myDynHilighted; }
protected:
// ---------- PROTECTED METHODS ----------
@@ -271,6 +408,14 @@ class NIS_View : public V3d_OrthographicView
void* /* user data */,
Aspect_GraphicCallbackStruct* /* call data */);
Standard_EXPORT void redrawCallback();
/**
* Redraw all interactive contexts.
*/
Standard_EXPORT void redraw (const Handle_NIS_View& theView,
const NIS_Drawer::DrawType theType);
/**
* Register an interactive context for this view.
*/
@@ -283,13 +428,30 @@ class NIS_View : public V3d_OrthographicView
private:
// ---------- PRIVATE FIELDS ----------
struct NamedViewData {
TCollection_AsciiString Name;
Handle_NIS_ViewData Data;
};
NCollection_List<NIS_InteractiveContext *> myContexts;
Handle_NIS_InteractiveObject myDynHilighted;
Standard_Boolean myIsTopHilight : 1;
Standard_Boolean myIsTopDynHilight : 1;
Standard_Boolean myDoHilightSelected : 1;
Standard_Boolean myIsDrawArea : 1;
NCollection_Vector<NIS_InteractiveObject *> myDetected;
TColStd_PackedMapOfInteger myExListId;
Handle_OpenGl_Context myGlCtx;
Standard_Integer myViewport[4];
gp_XY myPixelSize;
gp_XY myViewSize;
gp_XYZ myProj; // view Z direction
gp_Trsf myTrsf;
NCollection_List<struct NamedViewData> myViewData;
void * myHDC;
void * myHGLRC;
friend class NIS_InteractiveContext;

57
src/NIS/NIS_ViewData.hxx Normal file
View File

@@ -0,0 +1,57 @@
// File: NIS_ViewData.hxx
// Created: 11.05.12 17:26
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2012
#ifndef NIS_ViewData_HeaderFile
#define NIS_ViewData_HeaderFile
#include <Standard_Transient.hxx>
#include <Standard_DefineHandle.hxx>
class NIS_View;
/**
* Data belonging to particular instances of NIS_View, to extend the basic features of NIS_View.
* There may be several data objects per View, distinguished by their names
* (method NIS_View::GetViewData)
* @see NIS_View
* @ingroup nis_library
*/
class NIS_ViewData : public Standard_Transient
{
public:
// ---------- PUBLIC METHODS ----------
/**
* Empty constructor.
*/
NIS_ViewData () : myView (0L) {}
/**
* Method that is called on every refresh cycle of NIS_View.
*/
Standard_EXPORT virtual void Init () = 0;
/**
* Query the host view.
*/
inline NIS_View* GetView () const
{ return myView; }
private:
NIS_View* myView;
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NIS_ViewData)
friend class NIS_View;
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NIS_ViewData, Standard_Transient)
#endif

114
src/OSD/OSD_MPData.cxx Normal file
View File

@@ -0,0 +1,114 @@
// File: OSD_MPData.cxx
// Created: 29.06.09 09:19
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2009
#include <OSD_MProcess.hxx>
#ifdef WNT
// 'this' : used in base member initializer list
#pragma warning(disable:4355)
#endif
static const OSD_MProcess * DummyProcessor = 0L;
//=======================================================================
//function : OSD_MPData
//purpose : Empty constructor
//=======================================================================
OSD_MPData::OSD_MPData ()
: myID (0u),
myPrevious (this),
myNext (this),
myThreadID (UINT_MAX),
myProcessor (* DummyProcessor),
myStatus (StatusEmpty)
{
myThreadID = UINT_MAX;
}
//=======================================================================
//function : OSD_MPData()
//purpose : Constructor
//=======================================================================
OSD_MPData::OSD_MPData (const OSD_MProcess& theProcessor)
: myPrevious (this),
myNext (this),
myThreadID (UINT_MAX),
myProcessor (theProcessor),
myStatus (StatusEmpty)
{
static volatile Standard_Size MyCounter = 0u;
myID = MyCounter++;
}
//=======================================================================
//function : ~OSD_MPData
//purpose : Destructor
//=======================================================================
OSD_MPData::~OSD_MPData ()
{
}
//=======================================================================
//function : AddBefore
//purpose : Insert a new data object in the queue
//=======================================================================
void OSD_MPData::AddBefore (OSD_MPData * theAdded)
{
theAdded->myPrevious = myPrevious;
theAdded->myNext = this;
myPrevious->myNext = theAdded;
myPrevious = theAdded;
}
//=======================================================================
//function : Detach
//purpose : Remove this data object from the queue
//=======================================================================
void OSD_MPData::Detach ()
{
myPrevious->myNext = myNext;
myNext->myPrevious = myPrevious;
// myPrevious = this;
// myNext = this;
myThreadID = UINT_MAX;
}
//=======================================================================
//function : ThreadAlloc
//purpose : Get the thread-owned allocator instance
//=======================================================================
const Handle_NCollection_IncAllocator& OSD_MPData::ThreadAlloc() const
{
if (myThreadID == UINT_MAX) {
static Handle_NCollection_IncAllocator aNullAlloc;
aNullAlloc.Nullify();
return aNullAlloc;
}
return myProcessor.myArrThread[myThreadID].Allocator();
}
//=======================================================================
//function : Process
//purpose :
//=======================================================================
void OSD_MPData::Process ()
{
}
//=======================================================================
//function : PostProcess
//purpose :
//=======================================================================
void OSD_MPData::PostProcess ()
{
}

96
src/OSD/OSD_MPData.hxx Normal file
View File

@@ -0,0 +1,96 @@
// File: OSD_MPData.hxx
// Created: 29.06.09 09:01
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2009
#ifndef OSD_MPData_HeaderFile
#define OSD_MPData_HeaderFile
#include <NCollection_IncAllocator.hxx>
class OSD_MProcess;
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Data block processed by MP execution thread (OSD_MPThread)
*/
class OSD_MPData
{
public:
// ---------- PUBLIC METHODS ----------
enum Status {
StatusEmpty = 0, ///! empty data block, being initialized
StatusWait, ///! initialized with data, waiting for thread
StatusRequested, ///! Data requested by thread but not assigned
StatusProcess, ///! captured by thread, being processed
StatusDone, ///! released by thread after success
DummyData
};
//!Empty constructor.
Standard_EXPORT OSD_MPData ();
//! Consructor
Standard_EXPORT OSD_MPData (const OSD_MProcess& theProcessor);
//! Virtual destructor
Standard_EXPORT virtual ~OSD_MPData ();
//!! Allocator-based operator new for dynamic allocations
inline void* operator new (Standard_Size theSz,
const Handle_NCollection_BaseAllocator& theAlloc)
{ return theAlloc->Allocate(theSz); }
//! Query the unique ID of the data block
inline Standard_Size ID () const { return myID; }
//! Query the ID of the holding thread
inline unsigned int ThreadID () const { return myThreadID; }
//! Get the thread-owned allocator instance
Standard_EXPORT const Handle_NCollection_IncAllocator&
ThreadAlloc() const;
//! Processing of the data block, implements the algorithm executed by thread
Standard_EXPORT virtual void Process ();
//! Retrieving the calculated data (optional). This method is executed
//! in main thread, from OSD_MProcess::TakeData
Standard_EXPORT virtual void PostProcess ();
private:
//! Insert a new data object in the queue
Standard_EXPORT void AddBefore (OSD_MPData * theAdded);
//! Remove this data object from the queue.
Standard_EXPORT void Detach ();
OSD_MPData (const OSD_MPData& theOther);
OSD_MPData& operator= (const OSD_MPData& theOther);
private:
// ---------- PRIVATE FIELDS ----------
Standard_Size myID;
OSD_MPData * myPrevious;
OSD_MPData * myNext;
protected:
// ---------- PROTECTED FIELDS ----------
const OSD_MProcess& myProcessor;
volatile unsigned int myThreadID;
volatile Status myStatus;
friend class OSD_MProcess;
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

434
src/OSD/OSD_MProcess.cxx Normal file
View File

@@ -0,0 +1,434 @@
// File: OSD_MProcess.cxx
// Created: 29.06.09 09:40
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2009
#include <OSD_MProcess.hxx>
#ifdef WNT
// 'this' : used in base member initializer list
#pragma warning(disable:4355)
#endif
static Standard_Integer Delay (const unsigned int theValue);
//=======================================================================
//function : MPThread::MPThread
//purpose : Constructor
//=======================================================================
OSD_MProcess::MPThread::MPThread ()
: myProcessor (0L),
mypData (0L),
myID (UINT_MAX),
myNProcessed(0u),
myAlloc (new NCollection_IncAllocator),
myIsBusy (Standard_False),
myIsActive (Standard_False),
myIsSleeping(Standard_False)
{
}
//=======================================================================
//function : Process
//purpose : Thread function
//=======================================================================
Standard_Address OSD_MProcess::MPThread::Process(Standard_Address pThread)
{
MPThread& aThread = * reinterpret_cast<MPThread *> (pThread);
const OSD_MProcess& aMP = * aThread.myProcessor;
OSD_MPData * aBaseData = aThread.mypData;
OSD_MPData * aData = aBaseData;
aThread.myIsActive = Standard_True;
Standard_Integer aSleepCounter(0);
while (aThread.myIsActive) {
// Seek a waiting data block and process it
if (processData(aThread, aData, aBaseData, aSleepCounter))
{
if (aSleepCounter < 100 || aMP.AllowSleep() == Standard_False)
Delay(100);
else {
aThread.myIsBusy = Standard_False;
aThread.myIsSleeping = Standard_True;
Sleep(1);
aThread.myIsSleeping = Standard_False;
}
if (++aSleepCounter > 100)
aThread.myIsBusy = Standard_False;
}
}
return 0L;
}
//=======================================================================
//function : processData
//purpose :
//=======================================================================
Standard_Boolean OSD_MProcess::processData (MPThread& aThread,
OSD_MPData*& theData,
OSD_MPData* theBaseData,
Standard_Integer& aSleepCounter)
{
const Standard_Size aThreadID = aThread.myID;
Standard_Boolean isWait(Standard_True);
if (theData) {
isWait = Standard_False;
OSD_MPData * aData = theData->myNext;
while (aData != theBaseData)
{
if (aData->myStatus == OSD_MPData::StatusWait)
{
InterlockedCompareExchange((volatile LONG *)&aData->myThreadID,
aThreadID, UINT_MAX);
if (aData->myThreadID == aThreadID)
{
aData->myStatus = OSD_MPData::StatusProcess;
aThread.myIsBusy = Standard_True;
aSleepCounter = 0;
aData->Process();
aThread.myNProcessed++;
aData->myStatus = OSD_MPData::StatusDone;
aThread.mypData = aData;
break;
}
}
aData = aData->myNext;
}
if (aData == theBaseData) {
isWait = Standard_True;
}
theData = aData;
}
return isWait;
}
//=======================================================================
//function : OSD_MProcess()
//purpose : Constructor
//=======================================================================
OSD_MProcess::OSD_MProcess ()
: myNThreads (0),
myArrThread (0L),
myNDataAll (0u),
myIsSleepy (Standard_False)
{
myData.myStatus = OSD_MPData::DummyData;
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void OSD_MProcess::Init (const Standard_Size nThreads,
const Standard_Integer thePriority)
{
if (myNThreads)
Clear();
myAlloc = new NCollection_IncAllocator;
myNThreads = nThreads;
myIsSleepy = Standard_False;
myArrThread = new MPThread[nThreads + 1];
for (Standard_Size iThread = 0; iThread <= nThreads; iThread++) {
myArrThread[iThread].myProcessor = this;
myArrThread[iThread].myID = iThread;
myArrThread[iThread].mypData = &myData;
if (iThread) {
myArrThread[iThread].SetFunction(&MPThread::Process);
myArrThread[iThread].SetPriority(thePriority);
myArrThread[iThread].Run(&myArrThread[iThread]);
}
}
}
//=======================================================================
//function : OSD_MProcess()
//purpose : Constructor
//=======================================================================
OSD_MProcess::OSD_MProcess (const Standard_Size nThreads,
const Standard_Integer thePriority)
: myAlloc (new NCollection_IncAllocator),
myNThreads (nThreads),
myArrThread (new MPThread[nThreads + 1]),
myNDataAll (0u),
myIsSleepy (Standard_False)
{
myData.myStatus = OSD_MPData::DummyData;
for (Standard_Size iThread = 0; iThread <= nThreads; iThread++) {
myArrThread[iThread].myProcessor = this;
myArrThread[iThread].myID = iThread;
myArrThread[iThread].mypData = &myData;
if (iThread) {
myArrThread[iThread].SetFunction(&MPThread::Process);
myArrThread[iThread].SetPriority(thePriority);
myArrThread[iThread].Run(&myArrThread[iThread]);
}
}
}
//=======================================================================
//function : ~OSD_MProcess
//purpose : Destructor
//=======================================================================
OSD_MProcess::~OSD_MProcess ()
{
Clear();
}
//=======================================================================
//function : NProcessed
//purpose :
//=======================================================================
Standard_Size OSD_MProcess::NProcessed () const
{
Standard_Size aSum(0u);
for (Standard_Size i = 0; i <= myNThreads; i++)
aSum += myArrThread[i].myNProcessed;
return aSum;
}
//=======================================================================
//function : AddData
//purpose : Put a data block into the queue.
//=======================================================================
void OSD_MProcess::AddData (OSD_MPData * theData)
{
theData->myStatus = OSD_MPData::StatusEmpty;
theData->myThreadID = UINT_MAX;
myData.AddBefore(theData);
myNDataAll++;
theData->myStatus = OSD_MPData::StatusWait;
}
//=======================================================================
//function : TakeData
//purpose : Extract already processed data block, removing it from the queue.
//=======================================================================
OSD_MPData * OSD_MProcess::TakeData ()
{
OSD_MPData * aData = 0L;
const OSD_MPData * pBaseData = &myData;
OSD_MPData * pData = pBaseData->myNext;
for (; pData != pBaseData; pData = pData->myNext) {
if (pData->myStatus == OSD_MPData::StatusDone) {
pData->PostProcess();
myNDataAll--;
pData->Detach();
aData = pData;
break;
}
}
return aData;
}
//=======================================================================
//function : Wait
//purpose : Wait for the time theMillisec
//=======================================================================
Standard_Boolean OSD_MProcess::Wait (const Standard_Integer theMillisec,
const Standard_Boolean doTasks)
{
// Wait till all threads conclude
Standard_Boolean aResult(Standard_True);
Standard_Size i;
if (theMillisec > 0)
Sleep(theMillisec);
else if (doTasks)
myArrThread[0].mypData = &myData;
for (;;)
{
for (i = 1; i <= myNThreads; i++) {
if (myArrThread[i].IsBusy()) {
aResult = Standard_False;
break;
}
}
if (aResult) {
OSD_MPData * pData = myData.myNext;
for (; pData != &myData; pData = pData->myNext) {
if (pData->myStatus != OSD_MPData::StatusDone) {
aResult = Standard_False;
break;
}
}
if (aResult)
break;
}
if (theMillisec > 0)
break;
if (doTasks) {
OSD_MPData * aData = myArrThread[0].mypData;
Standard_Integer aSleepCounter(0);
// Seek a waiting data block and process it
processData(myArrThread[0], aData, &myData, aSleepCounter);
} else if (myIsSleepy)
Sleep(1);
aResult = Standard_True;
}
return aResult;
}
//=======================================================================
//function : Open
//purpose :
//=======================================================================
void OSD_MProcess::Open() const
{
Standard_Integer aCounter(5);
while (aCounter) {
for (Standard_Size i = 1; i <= myNThreads; i++) {
if (myArrThread[i].IsBusy())
return;
}
Standard_Integer aFlag(0);
OSD_MPData * pData = myData.myNext;
if (pData == &myData)
break; // protect from the case when no Data are loaded
for (; pData != &myData; pData = pData->myNext) {
if (pData->myStatus == OSD_MPData::StatusDone)
aFlag |= 0x1;
else
aFlag |= 0x2;
if (aFlag == 3) {
aCounter--;
break;
}
}
if (aFlag == 0x1) // all having StatusDone
break;
}
}
//=======================================================================
//function : Close
//purpose :
//=======================================================================
void OSD_MProcess::Close()
{
Wait(0, Standard_True);
OSD_MPData * pData = myData.myNext;
for (; pData != &myData; pData = pData->myNext) {
if (pData->myStatus == OSD_MPData::StatusDone) {
pData->PostProcess();
myNDataAll--;
}
}
myData.myPrevious = &myData;
myData.myNext = &myData;
myNDataAll = 0;
for (Standard_Size i = 0; i <= myNThreads; i++) {
const Handle(NCollection_IncAllocator)& anAlloc =
myArrThread[i].Allocator();
anAlloc->Reset(Standard_False);
}
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void OSD_MProcess::Clear(const Standard_Boolean isWait)
{
// Stop all threads
for (Standard_Size iThread = 1; iThread <= myNThreads; iThread++) {
myArrThread[iThread].myIsActive = Standard_False;
if (isWait)
myArrThread[iThread].Wait();
}
// Collect the data
if (isWait) {
OSD_MPData * pData = myData.myNext;
for (; pData != &myData; pData = pData->myNext) {
if (pData->myStatus == OSD_MPData::StatusDone) {
pData->PostProcess();
myNDataAll--;
}
}
}
// Free the resources
myData.myPrevious = &myData;
myData.myNext = &myData;
if (myNThreads) {
myNThreads = 0;
delete [] myArrThread;
myAlloc.Nullify();
myNDataAll = 0;
}
}
//=======================================================================
//function : Delay
//purpose : local function; delays proportionally to the given value
//=======================================================================
Standard_Integer Delay (const unsigned int theValue)
{
volatile Standard_Integer aSum = 1;
for (unsigned int i = 0; i < theValue; i++)
aSum += aSum / (i+1);
return aSum;
}
//=======================================================================
//function : AllowSleep
//purpose :
//=======================================================================
Standard_Boolean OSD_MProcess::AllowSleep () const
{
if (myIsSleepy)
return Standard_True;
Standard_Integer nAwake(myNThreads);
for (Standard_Size i = 1; i <= myNThreads; i++) {
if (myArrThread[i].myIsSleeping)
nAwake--;
}
return (nAwake >= GetMaxThreads());
}
//=======================================================================
//function : getMaxThreads
//purpose :
//=======================================================================
Standard_Integer OSD_MProcess::GetMaxThreads()
{
#ifdef WNT
#pragma warning(disable:4996)
#endif
static Standard_Integer nThreads(0);
if (nThreads == 0) {
char * strVar = getenv("OMP_NUM_THREADS");
if (strVar) {
nThreads = atoi(strVar);
if (nThreads == 0)
nThreads = -1;
}
if (nThreads < 0)
nThreads = 0;
else if (nThreads == 0) {
strVar = getenv("NUMBER_OF_PROCESSORS");
if (strVar)
nThreads = atoi(strVar);
}
}
return nThreads;
}

181
src/OSD/OSD_MProcess.hxx Normal file
View File

@@ -0,0 +1,181 @@
// File: OSD_MProcess.hxx
// Created: 29.06.09 09:34
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2009
#ifndef OSD_MProcess_HeaderFile
#define OSD_MProcess_HeaderFile
#include <OSD_MPData.hxx>
#include <OSD_Thread.hxx>
/**
* Manager of calculations in multiple threads (OSD_MPThread)
*/
class OSD_MProcess
{
public:
class MPThread : public OSD_Thread
{
public:
//! Constructor.
Standard_EXPORT MPThread ();
//! Thread function
static Standard_Address Process(Standard_Address);
//! Query if the thread is busy or idle.
inline Standard_Boolean IsBusy () const { return myIsBusy; }
//! Get the thread-owned memory Allocator
inline const Handle_NCollection_IncAllocator&
Allocator() const { return myAlloc; }
private:
MPThread (const MPThread& theOther);
MPThread& operator= (const MPThread& theOther);
private:
// ---------- PRIVATE FIELDS ----------
const OSD_MProcess * myProcessor;
OSD_MPData * mypData;
unsigned int myID;
Standard_Boolean myIsBusy;
Standard_Size myNProcessed;
Handle_NCollection_IncAllocator myAlloc;
volatile Standard_Boolean myIsActive;
volatile Standard_Boolean myIsSleeping;
friend class OSD_MProcess;
};
// ---------- PUBLIC METHODS ----------
/**
* Default constructor.
*/
Standard_EXPORT OSD_MProcess ();
/**
* Constructor. Starts the threads immediately.
*/
Standard_EXPORT OSD_MProcess (const Standard_Size nThreads,
const Standard_Integer thePriority = 0);
/**
* Initialize threads and start them. Used after empty constructor or Close
*/
Standard_EXPORT void Init (const Standard_Size nThreads,
const Standard_Integer thePriority = 0);
/**
* Destructor.
*/
Standard_EXPORT ~OSD_MProcess ();
//! Query the maximal advisable number of threads for this system.
static Standard_EXPORT Standard_Integer
GetMaxThreads ();
//! Query the number of opened threads
inline Standard_Size NThreads () const { return myNThreads; }
//! Query the length of the data queue
inline Standard_Size NData () const { return myNDataAll; }
//! Query the number of already processed data blocks
Standard_EXPORT Standard_Size
NProcessed () const;
//! Get the Allocator, to allocate new OSD_MPData instances
inline const Handle_NCollection_IncAllocator&
Allocator () const { return myAlloc; }
/**
* Put a data block into the queue.
*/
Standard_EXPORT void AddData (OSD_MPData * theData);
/**
* Extract already processed data block, removing it from the queue.
* Returns NULL if not available.
*/
Standard_EXPORT OSD_MPData *
TakeData ();
/**
* Wait for the time theMsec then return True if the execution is finished
* or False if it still continues. If theMillisec <= 0, then the method
* waits until all threads are exhausted.
*/
Standard_EXPORT Standard_Boolean
Wait (const Standard_Integer theMsec = 0,
const Standard_Boolean doTasks = 0u);
/**
* Avoid future sleeping of the managed threads, this reduces the delays
* during Open() and Close() calls. Call this method if it is expected to
* call Open/Close repeatedly for untensive processing.
*/
inline void GoAwake ()
{ myIsSleepy = Standard_False; }
/**
* Returns True if a Thread is allowed to sleep. Called from thread functions.
*/
Standard_EXPORT Standard_Boolean
AllowSleep () const;
/**
* Allow future sleeping of managed threads. This method shoul be called if
* there is not expected any intensive operation with repeated Open/Close.
*/
inline void GoSleepy ()
{ myIsSleepy = Standard_True; }
/**
* Query the Sleepy state
*/
inline Standard_Boolean IsSleepy () const
{ return myIsSleepy; }
/**
* Wait till the 1st task is started.
*/
Standard_EXPORT void Open () const;
/**
* Closes the processing without stopping the threads.
*/
Standard_EXPORT void Close ();
/**
* Stops the threads.
*/
Standard_EXPORT void Clear (const Standard_Boolean isWait = Standard_True);
private:
OSD_MProcess (const OSD_MProcess& theOther);
OSD_MProcess& operator- (const OSD_MProcess& theOther);
static Standard_Boolean processData (MPThread& aThread,
OSD_MPData*& theData,
OSD_MPData* theBaseData,
Standard_Integer& aSleepCounter);
private:
// ---------- PRIVATE FIELDS ----------
Handle_NCollection_IncAllocator myAlloc;
Standard_Size myNThreads;
OSD_MPData myData;
MPThread * myArrThread;
Standard_Size myNDataAll;
Standard_Boolean myIsSleepy;
friend class OSD_MPData;
};
#endif

Some files were not shown because too many files have changed in this diff Show More