0022353: EDF GEOM: Projection on a edge or a wire

This commit is contained in:
skv 2013-10-21 09:02:19 +00:00
parent 0993b9bfd3
commit d1573ebea6
12 changed files with 419 additions and 28 deletions

View File

@ -32,3 +32,17 @@ geompy.addToStudy(p4, "p4")
geompy.addToStudy(p5, "p5")
geompy.addToStudy(curve, "curve")
geompy.addToStudy(projection, "projection")
#projection of point on wire.
e1 = geompy.MakeLineTwoPnt(p1, p2)
e2 = geompy.MakeLineTwoPnt(p2, p3)
w1 = geompy.MakeWire([e1, e2], 1.e-7)
v1 = geompy.MakeVertex(300, 40, 100)
prj = geompy.MakeProjectionOnWire(v1, w1)
geompy.addToStudy(e1, "e1")
geompy.addToStudy(e2, "e2")
geompy.addToStudy(w1, "w1")
geompy.addToStudy(v1, "v1")
geompy.addToStudy(prj[1], "projOnWire")

View File

@ -1268,6 +1268,23 @@ module GEOM
*/
GEOM_Object ProjectShapeCopy (in GEOM_Object theSource, in GEOM_Object theTarget);
/*!
* \brief Create a projection projection of the given point on a wire or
* an edge.
*
* If there are no solutions or there are 2 or more solutions It throws an
* exception.
* \param thePoint the point to be projected.
* \param theWire the wire. The edge is accepted as well.
* \param thePointOnEdge the projection point.
* \param theEdgeInWireIndex the index of an edge in a wire.
* \return the parameter of projection point on edge.
*/
double ProjectPointOnWire (in GEOM_Object thePoint,
in GEOM_Object theWire,
out GEOM_Object thePointOnEdge,
out long theEdgeInWireIndex);
/*!
* \brief Scale the given object by the factor.
* \param theObject The object to be scaled.

View File

@ -92,6 +92,7 @@ SET(GEOMImpl_HEADERS
GEOMImpl_IMarker.hxx
GEOMImpl_ITranslate.hxx
GEOMImpl_IMirror.hxx
GEOMImpl_IProjection.hxx
GEOMImpl_IOffset.hxx
GEOMImpl_IScale.hxx
GEOMImpl_IRotate.hxx

View File

@ -0,0 +1,51 @@
// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
//NOTE: This is an interface to a function for the Projection creation.
#include "GEOM_Function.hxx"
#define PROJECTION_ARG_POINT 1
#define PROJECTION_ARG_SHAPE 2
#define PROJECTION_ARG_PARAMETER 3
#define PROJECTION_ARG_INDEX 4
class GEOMImpl_IProjection
{
public:
GEOMImpl_IProjection(Handle(GEOM_Function) theFunction): _func(theFunction) {}
void SetPoint (Handle(GEOM_Function) thePoint) { _func->SetReference(PROJECTION_ARG_POINT, thePoint); }
void SetShape (Handle(GEOM_Function) theShape) { _func->SetReference(PROJECTION_ARG_SHAPE, theShape); }
void SetU (double theU) { _func->SetReal(PROJECTION_ARG_PARAMETER, theU); }
void SetIndex (int theIndex) { _func->SetInteger(PROJECTION_ARG_INDEX, theIndex); }
Handle(GEOM_Function) GetPoint() { return _func->GetReference(PROJECTION_ARG_POINT); }
Handle(GEOM_Function) GetShape() { return _func->GetReference(PROJECTION_ARG_SHAPE); }
double GetU() { return _func->GetReal(PROJECTION_ARG_PARAMETER ); }
int GetIndex() { return _func->GetInteger(PROJECTION_ARG_INDEX); }
private:
Handle(GEOM_Function) _func;
};

View File

@ -34,6 +34,7 @@
#include <GEOMImpl_ITranslate.hxx>
#include <GEOMImpl_IMirror.hxx>
#include <GEOMImpl_IProjection.hxx>
#include <GEOMImpl_IOffset.hxx>
#include <GEOMImpl_IScale.hxx>
#include <GEOMImpl_IRotate.hxx>
@ -1236,6 +1237,77 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::ProjectShapeCopy
return aCopy;
}
//=============================================================================
/*!
* ProjectPointOnWire
*/
//=============================================================================
Standard_Real GEOMImpl_ITransformOperations::ProjectPointOnWire
(Handle(GEOM_Object) thePoint,
Handle(GEOM_Object) theWire,
Handle(GEOM_Object) &thePointOnEdge,
Standard_Integer &theEdgeInWireIndex)
{
Standard_Real aResult = -1.;
SetErrorCode(KO);
if (thePoint.IsNull() || theWire.IsNull()) {
return aResult;
}
Handle(GEOM_Function) aLastFunction = thePoint->GetLastFunction();
if (aLastFunction.IsNull()) {
//There is no function which creates an object to be projected
return aResult;
}
//Add a new Projection object
thePointOnEdge = GetEngine()->AddObject(GetDocID(), GEOM_PROJECTION);
//Add a Projection function
Handle(GEOM_Function) aFunction = thePointOnEdge->AddFunction
(GEOMImpl_ProjectionDriver::GetID(), PROJECTION_ON_WIRE);
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) {
return aResult;
}
GEOMImpl_IProjection aProj (aFunction);
aProj.SetPoint(aLastFunction);
aProj.SetShape(theWire->GetLastFunction());
//Compute the Projection
try {
#if OCC_VERSION_LARGE > 0x06010000
OCC_CATCH_SIGNALS;
#endif
if (!GetSolver()->ComputeFunction(aFunction)) {
SetErrorCode("Projection driver failed");
return aResult;
}
}
catch (Standard_Failure) {
Handle(Standard_Failure) aFail = Standard_Failure::Caught();
SetErrorCode(aFail->GetMessageString());
return aResult;
}
aResult = aProj.GetU();
theEdgeInWireIndex = aProj.GetIndex();
//Make a Python command
GEOM::TPythonDump(aFunction) << "(u, " << thePointOnEdge
<< ", EdgeInWireIndex) = geompy.MakeProjectionOnWire(" << thePoint
<< ", " << theWire << ")";
SetErrorCode(OK);
return aResult;
}
//=============================================================================
/*!

View File

@ -113,6 +113,12 @@ class GEOMImpl_ITransformOperations : public GEOM_IOperations
Standard_EXPORT Handle(GEOM_Object) ProjectShapeCopy (Handle(GEOM_Object) theSource,
Handle(GEOM_Object) theTarget);
Standard_EXPORT Standard_Real ProjectPointOnWire
(Handle(GEOM_Object) thePoint,
Handle(GEOM_Object) theWire,
Handle(GEOM_Object) &thePointOnEdge,
Standard_Integer &theEdgeInWireIndex);
Standard_EXPORT Handle(GEOM_Object) ScaleShape (Handle(GEOM_Object) theObject,
Handle(GEOM_Object) thePoint,
double theFactor);

View File

@ -25,6 +25,7 @@
#include <GEOMImpl_ProjectionDriver.hxx>
#include <GEOMImpl_IMirror.hxx>
#include <GEOMImpl_IProjection.hxx>
#include <GEOMImpl_Types.hxx>
#include <GEOM_Function.hxx>
@ -32,6 +33,7 @@
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepOffsetAPI_NormalProjection.hxx>
#include <BRepTools.hxx>
@ -45,6 +47,7 @@
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Plane.hxx>
#include <gp_Trsf.hxx>
@ -82,11 +85,14 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
if (aFunction.IsNull()) return 0;
Standard_Integer aType = aFunction->GetType();
if (aType == PROJECTION_COPY) {
// Projection
TopoDS_Shape aShape;
gp_Trsf aTrsf;
GEOMImpl_IMirror TI (aFunction);
Standard_Integer aType = aFunction->GetType();
Handle(GEOM_Function) anOriginalFunction = TI.GetOriginal();
if (anOriginalFunction.IsNull()) return 0;
@ -94,8 +100,6 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
TopoDS_Shape anOriginal = anOriginalFunction->GetValue();
if (anOriginal.IsNull()) return 0;
// Projection
if (aType == PROJECTION_COPY) {
// Source shape (point, edge or wire)
if (anOriginal.ShapeType() != TopAbs_VERTEX &&
anOriginal.ShapeType() != TopAbs_EDGE &&
@ -215,6 +219,151 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons
aFunction->SetValue(aShape);
log.SetTouched(Label());
} else if (aType == PROJECTION_ON_WIRE) {
// Perform projection of point on a wire or an edge.
GEOMImpl_IProjection aProj (aFunction);
Handle(GEOM_Function) aPointFunction = aProj.GetPoint();
Handle(GEOM_Function) aShapeFunction = aProj.GetShape();
if (aPointFunction.IsNull() || aShapeFunction.IsNull()) {
return 0;
}
TopoDS_Shape aPoint = aPointFunction->GetValue();
TopoDS_Shape aShape = aShapeFunction->GetValue();
if (aPoint.IsNull() || aShape.IsNull()) {
return 0;
}
// Check shape types.
if (aPoint.ShapeType() != TopAbs_VERTEX) {
Standard_ConstructionError::Raise
("Projection aborted : the point is not a vertex");
}
if (aShape.ShapeType() != TopAbs_EDGE &&
aShape.ShapeType() != TopAbs_WIRE) {
Standard_ConstructionError::Raise
("Projection aborted : the shape is neither an edge nor a wire");
}
// Perform projection.
BRepExtrema_DistShapeShape aDistShSh(aPoint, aShape, Extrema_ExtFlag_MIN);
if (aDistShSh.IsDone() == Standard_False) {
Standard_ConstructionError::Raise("Projection not done");
}
Standard_Boolean hasValidSolution = Standard_False;
Standard_Integer aNbSolutions = aDistShSh.NbSolution();
Standard_Integer i;
double aParam = 0.;
Standard_Real aTolConf = BRep_Tool::Tolerance(TopoDS::Vertex(aPoint));
Standard_Real aTolAng = 1.e-4;
for (i = 1; i <= aNbSolutions; i++) {
Standard_Boolean isValid = Standard_False;
BRepExtrema_SupportType aSupportType = aDistShSh.SupportTypeShape2(i);
TopoDS_Shape aSupportShape = aDistShSh.SupportOnShape2(i);
if (aSupportType == BRepExtrema_IsOnEdge) {
// Minimal distance inside edge is really a projection.
isValid = Standard_True;
aDistShSh.ParOnEdgeS2(i, aParam);
} else if (aSupportType == BRepExtrema_IsVertex) {
TopExp_Explorer anExp(aShape, TopAbs_EDGE);
if (aDistShSh.Value() <= aTolConf) {
// The point lies on the shape. This means this point
// is really a projection.
for (; anExp.More() && !isValid; anExp.Next()) {
TopoDS_Edge aCurEdge = TopoDS::Edge(anExp.Current());
if (aCurEdge.IsNull() == Standard_False) {
TopoDS_Vertex aVtx[2];
TopExp::Vertices(aCurEdge, aVtx[0], aVtx[1]);
for (int j = 0; j < 2; j++) {
if (aSupportShape.IsSame(aVtx[j])) {
// The current edge is a projection edge.
isValid = Standard_True;
aSupportShape = aCurEdge;
aParam = BRep_Tool::Parameter(aVtx[j], aCurEdge);
break;
}
}
}
}
} else {
// Minimal distance to vertex is not always a real projection.
gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aPoint));
gp_Pnt aPrjPnt = BRep_Tool::Pnt(TopoDS::Vertex(aSupportShape));
gp_Vec aDProjP(aPrjPnt, aPnt);
for (; anExp.More() && !isValid; anExp.Next()) {
TopoDS_Edge aCurEdge = TopoDS::Edge(anExp.Current());
if (aCurEdge.IsNull() == Standard_False) {
TopoDS_Vertex aVtx[2];
TopExp::Vertices(aCurEdge, aVtx[0], aVtx[1]);
for (int j = 0; j < 2; j++) {
if (aSupportShape.IsSame(aVtx[j])) {
// Check if the point is a projection to the current edge.
Standard_Real anEdgePars[2];
Handle(Geom_Curve) aCurve =
BRep_Tool::Curve(aCurEdge, anEdgePars[0], anEdgePars[1]);
gp_Pnt aVal;
gp_Vec aD1;
aParam = BRep_Tool::Parameter(aVtx[j], aCurEdge);
aCurve->D1(aParam, aVal, aD1);
if (Abs(aD1.Dot(aDProjP)) <= aTolAng) {
// The current edge is a projection edge.
isValid = Standard_True;
aSupportShape = aCurEdge;
break;
}
}
}
}
}
}
}
if (isValid) {
if (hasValidSolution) {
Standard_ConstructionError::Raise
("Projection aborted : multiple solutions");
}
// Store the valid solution.
hasValidSolution = Standard_True;
aProj.SetU(aParam);
// Compute edge index.
TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(aShape, anIndices);
const int anIndex = anIndices.FindIndex(aSupportShape);
aProj.SetIndex(anIndex);
// Construct a projection vertex.
const gp_Pnt &aPntProj = aDistShSh.PointOnShape2(i);
TopoDS_Shape aProj = BRepBuilderAPI_MakeVertex(aPntProj).Shape();
aFunction->SetValue(aProj);
}
}
if (!hasValidSolution) {
Standard_ConstructionError::Raise("Projection aborted : no projection");
}
}
return 1;

View File

@ -177,6 +177,7 @@
#define OFFSET_THICKENING_COPY 4
#define PROJECTION_COPY 1
#define PROJECTION_ON_WIRE 2
#define SCALE_SHAPE 1
#define SCALE_SHAPE_COPY 2

View File

@ -692,6 +692,39 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::ProjectShapeCopy
return GetObject(anObject);
}
//=============================================================================
/*!
* ProjectPointOnWire
*/
//=============================================================================
CORBA::Double GEOM_ITransformOperations_i::ProjectPointOnWire
(GEOM::GEOM_Object_ptr thePoint,
GEOM::GEOM_Object_ptr theWire,
GEOM::GEOM_Object_out thePointOnEdge,
CORBA::Long& theEdgeInWireIndex)
{
//Set a not done flag
GetOperations()->SetNotDone();
//Get the reference shape
Handle(GEOM_Object) aPoint = GetObjectImpl(thePoint);
Handle(GEOM_Object) aWire = GetObjectImpl(theWire);
if (aPoint.IsNull() || aWire.IsNull()) {
return -1.0;
}
Handle(GEOM_Object) aPointOnEdge;
CORBA::Double aResult = GetOperations()->ProjectPointOnWire
(aPoint, aWire, aPointOnEdge, theEdgeInWireIndex);
if (!aPointOnEdge.IsNull()) {
thePointOnEdge = GetObject(aPointOnEdge);
}
return aResult;
}
//=============================================================================
/*!
* ScaleShape

View File

@ -143,6 +143,11 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i :
GEOM::GEOM_Object_ptr ProjectShapeCopy (GEOM::GEOM_Object_ptr theSource,
GEOM::GEOM_Object_ptr theTarget);
CORBA::Double ProjectPointOnWire (GEOM::GEOM_Object_ptr thePoint,
GEOM::GEOM_Object_ptr theWire,
GEOM::GEOM_Object_out thePointOnEdge,
CORBA::Long& theEdgeInWireIndex);
GEOM::GEOM_Object_ptr ScaleShape (GEOM::GEOM_Object_ptr theObject,
GEOM::GEOM_Object_ptr thePoint,
CORBA::Double theFactor);

View File

@ -248,6 +248,7 @@ def TestAll (geompy, math):
Position2 = geompy.PositionAlongPath(Box, Arc, 0.5, 1, 0) #(2 GEOM_Object, 1 Double, 2 Bool)->GEOM_Object
Offset = geompy.MakeOffset(Box, 10.) #(GEOM_Object, Double)->GEOM_Object
Orientation = geompy.ChangeOrientation(Box)
ProjOnWire = geompy.MakeProjectionOnWire(p0, Wire)
#IDList for Fillet/Chamfer
prism_edges = geompy.ExtractShapes(Prism, geompy.ShapeType["EDGE"], True)
@ -456,6 +457,7 @@ def TestAll (geompy, math):
id_Position2 = geompy.addToStudy(Position2, "Positioned box along path")
id_Offset = geompy.addToStudy(Offset, "Offset")
id_Orientation = geompy.addToStudy(Orientation, "Orientation")
id_ProjOnWire = geompy.addToStudy(ProjOnWire[1], "ProjOnWire")
id_Fillet = geompy.addToStudy(Fillet, "Fillet")
id_Fillet2 = geompy.addToStudy(Fillet2, "Fillet2")

View File

@ -8037,6 +8037,46 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
self._autoPublish(anObj, theName, "projection")
return anObj
## Create a projection projection of the given point on a wire or an edge.
# If there are no solutions or there are 2 or more solutions It throws an
# exception.
# @param thePoint the point to be projected.
# @param theWire the wire. The edge is accepted as well.
# @param theName Object name; when specified, this parameter is used
# for result publication in the study. Otherwise, if automatic
# publication is switched on, default value is used for result name.
#
# @return [\a u, \a PointOnEdge, \a EdgeInWireIndex]
# \n \a u: The parameter of projection point on edge.
# \n \a PointOnEdge: The projection point.
# \n \a EdgeInWireIndex: The index of an edge in a wire.
#
# @ref tui_projection "Example"
def MakeProjectionOnWire(self, thePoint, theWire, theName=None):
"""
Create a projection projection of the given point on a wire or an edge.
If there are no solutions or there are 2 or more solutions It throws an
exception.
Parameters:
thePoint the point to be projected.
theWire the wire. The edge is accepted as well.
theName Object name; when specified, this parameter is used
for result publication in the study. Otherwise, if automatic
publication is switched on, default value is used for result name.
Returns:
[u, PointOnEdge, EdgeInWireIndex]
u: The parameter of projection point on edge.
PointOnEdge: The projection point.
EdgeInWireIndex: The index of an edge in a wire.
"""
# Example: see GEOM_TestAll.py
anObj = self.TrsfOp.ProjectPointOnWire(thePoint, theWire)
RaiseIfFailed("ProjectPointOnWire", self.TrsfOp)
self._autoPublish(anObj[1], theName, "projection")
return anObj
# -----------------------------------------------------------------------------
# Patterns
# -----------------------------------------------------------------------------