Sketcher: new attachment engine
This commit is contained in:
parent
061747f367
commit
42ecc24ec5
|
@ -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();
|
||||
|
|
131
src/Mod/Part/App/AttachableObject.cpp
Normal file
131
src/Mod/Part/App/AttachableObject.cpp
Normal 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());
|
||||
}
|
||||
|
||||
|
110
src/Mod/Part/App/AttachableObject.h
Normal file
110
src/Mod/Part/App/AttachableObject.h
Normal 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
|
1045
src/Mod/Part/App/Attacher.cpp
Normal file
1045
src/Mod/Part/App/Attacher.cpp
Normal file
File diff suppressed because it is too large
Load Diff
265
src/Mod/Part/App/Attacher.h
Normal file
265
src/Mod/Part/App/Attacher.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue
Block a user