Sketcher: new attachment engine

This commit is contained in:
DeepSOIC 2015-06-29 20:27:52 +03:00 committed by Stefan Tröger
parent 061747f367
commit 42ecc24ec5
9 changed files with 1565 additions and 181 deletions

View File

@ -51,6 +51,7 @@
#include "PartFeatures.h"
#include "BodyBase.h"
#include "PrimitiveFeature.h"
#include "Attacher.h"
#include "Part2DObject.h"
#include "CustomFeature.h"
#include "TopoShapePy.h"
@ -220,6 +221,7 @@ PyMODINIT_FUNC initPart()
Part::Feature ::init();
Part::FeatureExt ::init();
Part::AttachableObject ::init();
Part::BodyBase ::init();
Part::FeaturePython ::init();
Part::FeatureGeometrySet ::init();

View File

@ -0,0 +1,131 @@
/***************************************************************************
* Copyright (c) Victor Titov (DeepSOIC) *
* (vv.titov@gmail.com) 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "AttachableObject.h"
#include <Base/Console.h>
using namespace Part;
using namespace Attacher;
PROPERTY_SOURCE(Part::AttachableObject, Part::Feature);
AttachableObject::AttachableObject()
: _attacher(0)
{
ADD_PROPERTY_TYPE(Support, (0,0), "Attachment",(App::PropertyType)(App::Prop_None),"Support of the 2D geometry");
//It is necessary to default to mmToFlatFace, in order to load old files
ADD_PROPERTY_TYPE(MapMode, (mmFlatFace), "Attachment", App::Prop_None, "Mode of attachment to other object");
MapMode.setEnums(AttachEngine::eMapModeStrings);
ADD_PROPERTY_TYPE(MapReversed, (false), "Attachment", App::Prop_None, "Reverse Z direction (flip sketch upside down)");
ADD_PROPERTY_TYPE(MapPathParameter, (0.0), "Attachment", App::Prop_None, "Sets point of curve to map the sketch to. 0..1 = start..end");
ADD_PROPERTY_TYPE(superPlacement, (Base::Placement()), "Attachment", App::Prop_None, "Extra placement to apply in addition to attachment (in local coordinates)");
setAttacher(new AttachEngine3D);//default attacher
}
AttachableObject::~AttachableObject()
{
if(_attacher)
delete _attacher;
}
void AttachableObject::setAttacher(AttachEngine* attacher)
{
if (_attacher)
delete _attacher;
_attacher = attacher;
updateAttacherVals();
}
void AttachableObject::positionBySupport()
{
if (!_attacher)
return;
updateAttacherVals();
try{
this->Placement.setValue(_attacher->calculateAttachedPlacement(this->Placement.getValue()));
} catch (ExceptionCancel) {
//disabled, don't do anything
};
}
App::DocumentObjectExecReturn *AttachableObject::execute()
{
if(this->isTouched_Mapping()) {
try{
positionBySupport();
} catch (Base::Exception &e) {
return new App::DocumentObjectExecReturn(e.what());
} catch (Standard_Failure &e){
return new App::DocumentObjectExecReturn(e.GetMessageString());
}
}
return Part::Feature::execute();
}
void AttachableObject::onChanged(const App::Property* prop)
{
if(! this->isRestoring()){
try{
if ((prop == &Support
|| prop == &MapMode
|| prop == &MapPathParameter
|| prop == &MapReversed
|| prop == &superPlacement))
positionBySupport();
} catch (Base::Exception &e) {
this->setError();
Base::Console().Error("PositionBySupport: &s",e.what());
//set error message - how?
} catch (Standard_Failure &e){
this->setError();
Base::Console().Error("PositionBySupport: &s",e.GetMessageString());
}
}
Part::Feature::onChanged(prop);
}
void AttachableObject::updateAttacherVals()
{
if (!_attacher)
return;
_attacher->setUp(this->Support,
eMapMode(this->MapMode.getValue()),
this->MapReversed.getValue(),
this->MapPathParameter.getValue(),
0.0,0.0,
this->superPlacement.getValue());
}

View File

@ -0,0 +1,110 @@
/***************************************************************************
* Copyright (c) Victor Titov (DeepSOIC) *
* (vv.titov@gmail.com) 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
/**
* AttachableObject.h, .cpp contain a class to derive other features from, to make
* them attachable.
*/
#ifndef PARTATTACHABLEOBJECT_H
#define PARTATTACHABLEOBJECT_H
#include <App/PropertyStandard.h>
#include <App/PropertyLinks.h>
#include <App/GeoFeature.h>
#include <Base/Vector3D.h>
#include <Base/Placement.h>
#include <Base/Exception.h>
#include "PartFeature.h"
#include "Attacher.h"
#include <QString>
#include <gp_Vec.hxx>
using namespace Attacher;
namespace Part
{
/**
* @brief The AttachableObject class is the thing to be inherited by an object
* that should be attachable. It includes the required properties, and
* shortcuts for accessing the attachment math class.
*
* Todos to make it work:
* - call Attacher::execute() when executing derived object. Make sure to deal
* with its return value, otherwise it will leak memory upon fails.
*/
class PartExport AttachableObject : public Part::Feature
{
PROPERTY_HEADER(Part::AttachableObject);
public:
AttachableObject();
~AttachableObject();
/**
* @brief setAttacher sets the AttachEngine object. The class takes the
* ownership of the pointer, it will be deleted when the class is
* destroyed, or when a new attacher is set. The default attacher is AttachEngine3D.
* @param attacher. AttachableObject takes ownership and will delete it eventually.
*/
virtual void setAttacher(AttachEngine* attacher);
AttachEngine* attacher(void) const {return _attacher;}
/// if the 2DObject lies on the Face of an other object this links to it
App::PropertyLinkSubList Support;
App::PropertyEnumeration MapMode; //see AttachEngine::eMapMode
App::PropertyBool MapReversed; //inverts Z and X internal axes
App::PropertyPlacement superPlacement;
/**
* @brief MapPathParameter is a parameter value for mmNormalToPath (the
* sketch will be mapped normal to a curve at point specified by parameter
* (from 0.0 to 1.0, from start to end) )
*/
App::PropertyFloat MapPathParameter;
/** calculate and update the Placement property based on the Support, and
* mode. Can throw FreeCAD and OCC exceptions.
*/
virtual void positionBySupport(void);
virtual bool isTouched_Mapping()
{return true; /*support.isTouched isn't true when linked objects are changed... why?..*/};
App::DocumentObjectExecReturn *execute(void);
protected:
virtual void onChanged(const App::Property* /*prop*/);
public:
void updateAttacherVals();
private:
AttachEngine* _attacher;
};
} // namespace Part
#endif // PARTATTACHABLEOBJECT_H

File diff suppressed because it is too large Load Diff

265
src/Mod/Part/App/Attacher.h Normal file
View File

@ -0,0 +1,265 @@
/***************************************************************************
* Copyright (c) Victor Titov (DeepSOIC) *
* (vv.titov@gmail.com) 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
/**
*Attacher.h, Attacher.cpp contain the functionality of deriving placement
*from a set of geometric subelements. Examples are: sketch attachment, datum
*plane placement.
*/
#ifndef PARTATTACHER_H
#define PARTATTACHER_H
#include <App/PropertyStandard.h>
#include <App/PropertyLinks.h>
#include <App/GeoFeature.h>
#include <Base/Vector3D.h>
#include <Base/Placement.h>
#include <Base/Exception.h>
#include "PartFeature.h"
#include <QString>
#include <gp_Vec.hxx>
using namespace Part;
namespace Attacher
{
class AttachEngine;
enum eMapMode {
mmDeactivated,
mmTranslate,
mmObjectXY,
mmObjectXZ,
mmObjectYZ,
mmFlatFace,
mmTangentPlane,
mmNormalToPath,
mmFrenetNB,
mmFrenetTN,
mmFrenetTB,
mmConcentric,
mmRevolutionSection,
mmThreePointsPlane,
mmThreePointsNormal,
mmFolding,
mmDummy_NumberOfModes//a value useful to check the validity of mode value
};//see also eMapModeStrings[] definition in .cpp
enum eSuggestResult{
srOK,
srLinkBroken,
srUnexpectedError,
srNoModesFit,//none of the avaliable mapping modes accepts the set of topological type
srIncompatibleGeometry,//there is a mode that could fit, but geometry is wrong (e.g. a line is required, but a curve was passed).
};
/**
* @brief The eRefType enum lists the types of references. If adding one, see
* also AttachEngine::getShapeType() and AttachEngine::downgradeType()
*/
enum eRefType {
//topo //ranks: (number of times the type is downgradable)
rtAnything, //0
rtVertex, //1
rtEdge, //1
rtFace, //1
//edges:
rtLine, //2
rtCurve, //2
rtCircle, //3
//faces:
rtFlatFace, //2
rtCylindricalFace, //2
rtSphericalFace, //2
//shapes:
rtPart, //1
rtSolid, //2
rtWire, //2
rtDummy_numberOfShapeTypes//a value useful to check the validity of value
};
/**
* @brief The AttachEngine class is the placement calculation routine, modes,
* hints and so on. It can be used separately, without deriving from
* AttachableObject.
*/
class PartExport AttachEngine : public Base::BaseClass
{
TYPESYSTEM_HEADER();
public: //methods
AttachEngine();
virtual void setUp(const App::PropertyLinkSubList &references,
eMapMode mapMode = mmDeactivated,
bool mapReverse = false,
double attachParameter = 0.0,
double surfU = 0.0, double surfV = 0.0,
Base::Placement superPlacement = Base::Placement());
virtual AttachEngine* copy() const = 0;
virtual Base::Placement calculateAttachedPlacement(Base::Placement origPlacement) const = 0;
/**
* @brief listMapModes is the procedure that knows everything about
* mapping modes. It returns the most appropriate mapping mode, as well as
* list of all modes that will accept the set of references. In case no modes apply,
* extra information regarding reasons is returned in msg.
*
* @param msg (output). Returns a message from the decision logic: OK if
* the mode was chosen, a reason if not.
*
* @param allApplicableModes (output). Pointer to a vector array that will recieve the
* list of all modes that are applicable to the support. It doesn't
* guarantee that all modes will work, it only checks that subelemnts are of
* right type.
*
* @param nextRefTypeHint (output). A hint of what can be added to references.
*/
virtual eMapMode listMapModes(eSuggestResult &msg,
std::vector<eMapMode>* allApplicableModes = 0,
std::set<eRefType>* nextRefTypeHint = 0) const;
/**
* @brief getHint function returns a set of types that user can add to
* references to arrive to combinations valid for some modes. This function
* is a shoutcut to listMapModes.
*
* @return a set of selection types that can be appended to the support.
*
* Subclassing: This function works out of the box via a call to
* listMapModes, so there is no need to reimplement it.
*/
virtual const std::set<eRefType> getHint(bool forCurrentModeOnly) const;
virtual ~AttachEngine(){};
public://helper functions that may be useful outside of the class
static eRefType getShapeType(const TopoDS_Shape &sh);
/**
* @brief downgradeType converts a more-specific type into a less-specific
* type (e.g. rtCircle->rtCurve, rtCurve->rtEdge, rtEdge->rtAnything)
* @param type
* @return the downgraded type.
*/
static eRefType downgradeType(eRefType type);
/**
* @brief getTypeRank determines, how specific is the supplied shape type.
* The ranks are outlined in definition of eRefType. The ranks are defined
* by implementation of downgradeType().
* @param type
* @return number of times the type can be downgradeType() before it
* becomes rtAnything
*/
static int getTypeRank(eRefType type);
/**
* @brief isShapeOfType tests if a shape fulfills the requirement of a mode, and returns a score of how spot on was the requirement.
* @param shapeType (use return value of AttachEngine::getShapeType)
* @param requirement
* @return : -1 - doesn't fulfill,
* 0 - compatible topology, but incompatible specific (e.g. rtLine, rtCircle);
* 1 - valid by generic type (e.g. rtCircle is rtEdge),
* 2 and up - more and more specific match (according to rank of requirement)
*/
static int isShapeOfType(eRefType shapeType, eRefType requirement);
public: //enums
static const char* eMapModeStrings[];
public: //members
App::PropertyLinkSubList references;
eMapMode mapMode;
bool mapReverse;
double attachParameter;
double surfU, surfV;
Base::Placement superPlacement;
/**
* @brief modeEnabled is an indicator, whether some mode is ever suggested
* or not. Set to false to suppress suggesting some mode, like so:
* modeEnabled[mmModeIDontLike] = false;
*/
std::vector<bool> modeEnabled;
typedef std::vector<eRefType> refTypeString; //a sequence of ref types, according to Support contents for example
typedef std::vector<refTypeString> refTypeStringList; //a set of type strings, defines which selection sets are supported by a certain mode
std::vector<refTypeStringList> modeRefTypes; //a complete data structure, containing info on which modes support what selection
protected:
refTypeString cat(eRefType rt1){refTypeString ret; ret.push_back(rt1); return ret;}
refTypeString cat(eRefType rt1, eRefType rt2){refTypeString ret; ret.push_back(rt1); ret.push_back(rt2); return ret;}
refTypeString cat(eRefType rt1, eRefType rt2, eRefType rt3){refTypeString ret; ret.push_back(rt1); ret.push_back(rt2); ret.push_back(rt3); return ret;}
refTypeString cat(eRefType rt1, eRefType rt2, eRefType rt3, eRefType rt4){refTypeString ret; ret.push_back(rt1); ret.push_back(rt2); ret.push_back(rt3); ret.push_back(rt4); return ret;}
void readLinks(std::vector<App::GeoFeature *> &geofs, std::vector<const TopoDS_Shape*>& shapes, std::vector<TopoDS_Shape> &storage) const;
};
class PartExport AttachEngine3D : public AttachEngine
{
TYPESYSTEM_HEADER();
public:
AttachEngine3D();
virtual AttachEngine3D* copy() const;
virtual Base::Placement calculateAttachedPlacement(Base::Placement origPlacement) const;
private:
double calculateFoldAngle(gp_Vec axA, gp_Vec axB, gp_Vec edA, gp_Vec edB) const;
};
typedef AttachEngine3D AttachEnginePlane ;//no separate class for planes, for now. Can be added later, if required.
/*
class AttachEnginePlane : public AttachEngine
{
AttachEnginePlane();
virtual AttachEnginePlane* copy() const {return new AttachEnginePlane(*this);}
virtual Base::Placement calculateAttachedPlacement(void) const;
virtual eMapMode listMapModes(eSuggestResult &msg, std::vector<eMapMode>* allmodes = 0, std::vector<QString>* nextRefTypeHint = 0) const;
~AttachEnginePlane(){};
};
*/
//class AttachEnginePoint : public AttachEngine
//{
//
//};
class ExceptionCancel : public Base::Exception
{
public:
ExceptionCancel(){}
ExceptionCancel(char* msg){this->setMessage(msg);}
~ExceptionCancel(){}
};
} // namespace Attacher
#endif // PARTATTACHER_H

View File

@ -140,6 +140,8 @@ SET(Features_SRCS
BodyBase.cpp
DatumFeature.cpp
DatumFeature.h
AttachableObject.h
AttachableObject.cpp
)
SOURCE_GROUP("Features" FILES ${Features_SRCS})
@ -243,6 +245,8 @@ SET(Part_SRCS
${Features_SRCS}
${Properties_SRCS}
${Python_SRCS}
Attacher.cpp
Attacher.h
AppPart.cpp
AppPartPy.cpp
BSplineCurveBiArcs.cpp

View File

@ -59,7 +59,7 @@ const int Part2DObject::H_Axis = -1;
const int Part2DObject::V_Axis = -2;
const int Part2DObject::N_Axis = -3;
PROPERTY_SOURCE(Part::Part2DObject, Part::Feature)
PROPERTY_SOURCE(Part::Part2DObject, Part::AttachableObject)
Part2DObject::Part2DObject()
@ -69,170 +69,7 @@ Part2DObject::Part2DObject()
App::DocumentObjectExecReturn *Part2DObject::execute(void)
{
return App::DocumentObject::StdReturn;
}
void Part2DObject::positionBySupport(void)
{
AttachableObject::positionBySupport();
return;
/*
// recalculate support:
Base::Placement Place;
TopoDS_Shape sh;
bool Reverse = false;
gp_Pln plane;
App::DocumentObject* support = Support.getValues();
if (support == NULL)
return;
if (support->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
// Find the name of the Baseplane without having to access PartDesignGui::BaseplaneNames[]
Place = static_cast<App::Plane*>(support)->Placement.getValue();
Base::Vector3d dir;
Place.getRotation().multVec(Base::Vector3d(0,0,1),dir);
const std::vector<std::string> &sub = Support.getSubValues();
if (!sub.empty() && (sub[0] == "back"))
Reverse = true;
// Set placement identical to the way it used to be done in the Sketcher::SketchOrientationDialog
if (dir == Base::Vector3d(0,0,1)) {
if (Reverse)
Place = Base::Placement(Base::Vector3d(0,0,0),Base::Rotation(-1.0, 0.0,0.0,0.0));
else
Place = Base::Placement(Base::Vector3d(0,0,0),Base::Rotation());
} else if (dir == Base::Vector3d(0,1,0)) {
if (Reverse)
Place = Base::Placement(Base::Vector3d(0,0,0),Base::Rotation(Base::Vector3d(0,sqrt(2.0)/2.0,sqrt(2.0)/2.0),M_PI));
else
Place = Base::Placement(Base::Vector3d(0,0,0),Base::Rotation(Base::Vector3d(-1,0,0),1.5*M_PI));
} else if (dir == Base::Vector3d(1,0,0)) {
Place = Base::Placement(Base::Vector3d(0,0,0),Base::Rotation(Reverse ? -0.5 : 0.5,0.5,0.5, Reverse ? -0.5 : 0.5));
}
if (Reverse) {
dir *= -1.0;
Reverse = false; // We already reversed...
}
Place.getRotation().multVec(Base::Vector3d(0,0,1),dir);
Base::Vector3d pos = Place.getPosition();
plane = gp_Pln(gp_Pnt(pos.x, pos.y, pos.z), gp_Dir(dir.x, dir.y, dir.z));
} else if (support->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
const std::vector<std::string> &sub = Support.getSubValues();
assert(sub.size()==1);
Part::Datum* pcDatum = static_cast<Part::Datum*>(support);
Place = pcDatum->Placement.getValue();
Base::Vector3d dir;
Place.getRotation().multVec(Base::Vector3d(0,0,1),dir);
if (!sub.empty() && (sub[0] == "back"))
dir *= -1.0;
Base::Vector3d pos = Place.getPosition();
plane = gp_Pln(gp_Pnt(pos.x, pos.y, pos.z), gp_Dir(dir.x, dir.y, dir.z));
} else {
Part::Feature *part = static_cast<Part::Feature*>(support);
if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
return;
Place = part->Placement.getValue();
const std::vector<std::string> &sub = Support.getSubValues();
assert(sub.size()==1);
// get the selected sub shape (a Face)
const Part::TopoShape &shape = part->Shape.getShape();
if (shape._Shape.IsNull())
throw Base::Exception("Support shape is empty!");
try {
sh = shape.getSubShape(sub[0].c_str());
}
catch (Standard_Failure) {
throw Base::Exception("Face in support shape doesn't exist!");
}
const TopoDS_Face &face = TopoDS::Face(sh);
if (face.IsNull())
throw Base::Exception("Null face in Part2DObject::positionBySupport()!");
BRepAdaptor_Surface adapt(face);
if (adapt.GetType() != GeomAbs_Plane)
throw Base::Exception("No planar face in Part2DObject::positionBySupport()!");
if (face.Orientation() == TopAbs_REVERSED)
Reverse = true;
plane = adapt.Plane();
Standard_Boolean ok = plane.Direct();
if (!ok) {
// toggle if plane has a left-handed coordinate system
plane.UReverse();
Reverse = !Reverse;
}
}
gp_Ax1 Normal = plane.Axis();
if (Reverse)
Normal.Reverse();
gp_Pnt ObjOrg(Place.getPosition().x,Place.getPosition().y,Place.getPosition().z);
Handle (Geom_Plane) gPlane = new Geom_Plane(plane);
GeomAPI_ProjectPointOnSurf projector(ObjOrg,gPlane);
gp_Pnt SketchBasePoint = projector.NearestPoint();
gp_Dir dir = Normal.Direction();
gp_Ax3 SketchPos;
Base::Vector3d dX,dY,dZ;
Place.getRotation().multVec(Base::Vector3d(1,0,0),dX);
Place.getRotation().multVec(Base::Vector3d(0,1,0),dY);
Place.getRotation().multVec(Base::Vector3d(0,0,1),dZ);
gp_Dir dirX(dX.x, dX.y, dX.z);
gp_Dir dirY(dY.x, dY.y, dY.z);
gp_Dir dirZ(dZ.x, dZ.y, dZ.z);
double cosNX = dir.Dot(dirX);
double cosNY = dir.Dot(dirY);
double cosNZ = dir.Dot(dirZ);
std::vector<double> cosXYZ;
cosXYZ.push_back(fabs(cosNX));
cosXYZ.push_back(fabs(cosNY));
cosXYZ.push_back(fabs(cosNZ));
int pos = std::max_element(cosXYZ.begin(), cosXYZ.end()) - cosXYZ.begin();
// +X/-X
if (pos == 0) {
if (cosNX > 0)
SketchPos = gp_Ax3(SketchBasePoint, dir, dirY);
else
SketchPos = gp_Ax3(SketchBasePoint, dir, -dirY);
}
// +Y/-Y
else if (pos == 1) {
if (cosNY > 0)
SketchPos = gp_Ax3(SketchBasePoint, dir, -dirX);
else
SketchPos = gp_Ax3(SketchBasePoint, dir, dirX);
}
// +Z/-Z
else {
SketchPos = gp_Ax3(SketchBasePoint, dir, dirX);
}
gp_Trsf Trf;
Trf.SetTransformation(SketchPos);
Trf.Invert();
Trf.SetScaleFactor(Standard_Real(1.0));
Base::Matrix4D mtrx;
TopoShape::convertToMatrix(Trf,mtrx);
// check the angle against the Z Axis
//Standard_Real a = Normal.Angle(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1)));
Placement.setValue(Base::Placement(mtrx));
*/
return AttachableObject::execute();
}
void Part2DObject::transformPlacement(const Base::Placement &transform)
@ -240,8 +77,9 @@ void Part2DObject::transformPlacement(const Base::Placement &transform)
if (Support.getValues().size() > 0) {
//part->transformPlacement(transform);
positionBySupport();
} else
} else {
GeoFeature::transformPlacement(transform);
}
}
int Part2DObject::getAxisCount(void) const
@ -370,14 +208,6 @@ void Part2DObject::acceptGeometry()
// implemented in sub-classes
}
void Part2DObject::onChanged(const App::Property* prop)
{
// Update the Placement if the Support changes
if ((prop == &Support) && (Support.getValues().size() > 0))
positionBySupport();
Part::Feature::onChanged(prop);
}
// Python Drawing feature ---------------------------------------------------------
namespace App {

View File

@ -57,8 +57,6 @@ class PartExport Part2DObject : public Part::AttachableObject
public:
Part2DObject();
void positionBySupport();
virtual void transformPlacement(const Base::Placement &transform);
/// returns the number of construction lines (to be used as axes)
@ -95,9 +93,6 @@ public:
}
//@}
protected:
/// get called by the container when a property has changed
virtual void onChanged(const App::Property* /*prop*/);
};
typedef App::FeaturePythonT<Part2DObject> Part2DObjectPython;

View File

@ -128,8 +128,10 @@ SketchObject::~SketchObject()
App::DocumentObjectExecReturn *SketchObject::execute(void)
{
try {
if (Support.getSize() > 0)
this->positionBySupport();
App::DocumentObjectExecReturn* rtn = Part2DObject::execute();//to positionBySupport
if(rtn!=App::DocumentObject::StdReturn)
//error
return rtn;
}
catch (const Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what());