free-cad polyline stuff.

 

 

 

I think I honed on the section of code that needs to draw an arc instead of a polyline, but I wanted to figure out how to trap the letter “a” being depressed… Little “A” are you sad because your trapped… Errrrr… getting late here..

The suggestion from the freecad forum was to look at something here.

I think the magic search term for me at the moment is “->keyPressed” .

I think that I need create a boolean for an keyArc in the class ViewProviderSketch in the sketcher/gui. and set it here.

—————————————————————–

bool ViewProviderSketch::keyPressed(bool pressed, int key)
{
switch (key)
{
case SoKeyboardEvent::ESCAPE:
{
// make the handler quit but not the edit mode
if (edit && edit->sketchHandler) {
if (!pressed)
edit->sketchHandler->quit();
return true;
}
return false;
}
case SoKeyboardEvent::A: //Designation of an arc in polyline mode
{
keyArcPressed =pressed;
return true;

}

}

——————————————————-

class SketcherGuiExport ViewProviderSketch : public PartGui::ViewProvider2DObject, public Gui::SelectionObserver
{
PROPERTY_HEADER(PartGui::ViewProviderSketch);

public:
/// constructor
ViewProviderSketch();
/// destructor
virtual ~ViewProviderSketch();

App::PropertyBool Autoconstraints;

/// draw constraint icon given the constraint id
void drawConstraintIcons();
/// draw the sketch in the inventor nodes
void draw(bool temp=false);
/// draw the edit curve
void drawEdit(const std::vector<Base::Vector2D> &EditCurve);

/// Is the view provider selectable
bool isSelectable(void) const;
/// Observer message from the Selection
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);

/** @name handler control */
//@{
/// sets an DrawSketchHandler in control
void activateHandler(DrawSketchHandler *newHandler);
/// removes the active handler
void purgeHandler(void);
//@}

/** @name modus handling */
//@{
/// mode table
enum SketchMode{
STATUS_NONE,              /**< enum value View provider is in neutral. */
STATUS_SELECT_Point,      /**< enum value a point was selected. */
STATUS_SELECT_Edge,       /**< enum value a edge was selected. */
STATUS_SELECT_Constraint, /**< enum value a constraint was selected. */
STATUS_SELECT_Cross,      /**< enum value the base coordinate system was selected. */
STATUS_SKETCH_DragPoint,  /**< enum value while dragging a point. */
STATUS_SKETCH_DragCurve,  /**< enum value while dragging a curve. */
STATUS_SKETCH_DragConstraint,  /**< enum value while dragging a compatible constraint. */
STATUS_SKETCH_UseHandler  /**< enum value a DrawSketchHandler is in control. */
};
/// is called by GuiCommands to set the drawing mode
void setSketchMode(SketchMode mode) {Mode = mode;}
/// get the sketch mode
SketchMode getSketchMode(void) const {return Mode;}
//@}
  //JT
    enum PolylineElementMode{
        POLYLINE_ELEMENT_TYPE_Generic,
        POLYLINE_ELEMENT_TYPE_Arc //tangential to previous element assumed
        // potentially could add chamfer 30,45,60 degree
        //vertical line
        //horizontal line
        //perpenticular line
        //tangential line

};

PolylineElementMode getPolylineElementMode(void) const {return CurrentPolylineElementMode;}

/** @name helper functions */
//@{
/// give the coordinates of a line on the sketch plane in sketcher (2D) coordinates
void getCoordsOnSketchPlane(double &u, double &v,const SbVec3f &point, const SbVec3f &normal);
/// helper to detect preselection
//bool handlePreselection(const SoPickedPoint *pp);
/// helper to detect preselection
bool detectPreselection(const SoPickedPoint *Point, int &PtIndex,int &CurvIndex, int &ConstrIndex, int &CrossIndex);
/// helper change the color of the sketch according to selection and solver status
void updateColor(void);
/// get the pointer to the sketch document object
Sketcher::SketchObject *getSketchObject(void) const;

/// snap points x,y (mouse coordinates) onto grid if enabled
void snapToGrid(double &x, double &y);

/// moves a selected constraint
void moveConstraint(int constNum, const Base::Vector2D &toPos);
/// checks if there is a constraint object at position vector
bool isConstraintAtPosition(const Base::Vector3d &constrPos, const SoNode *constraint);
/// finds a free position for placing a constraint icon
Base::Vector3d seekConstraintPosition(const Base::Vector3d &suggestedPos,
const Base::Vector3d &dir, float step,
const SoNode *constraint);

float getScaleFactor();
int getPreselectPoint(void) const;
int getPreselectCurve(void) const;
int getPreselectConstraint(void) const;
//@}

/** @name base class implementer */
//@{
virtual void attach(App::DocumentObject *);
virtual void updateData(const App::Property *);

virtual void setupContextMenu(QMenu *menu, QObject *receiver, const char *member);
/// is called when the Provider is in edit and a deletion request occurs
virtual bool onDelete(const std::vector<std::string> &);
/// is called by the tree if the user double click on the object
virtual bool doubleClicked(void);
/// is called when the Provider is in edit and the mouse is moved
virtual bool mouseMove(const SbVec3f &pNear, const SbVec3f &pFar, const SoPickedPoint *pp);
/// is called when the Provider is in edit and a key event ocours. Only ESC ends edit.
virtual bool keyPressed(bool pressed, int key);
/// is called when the Provider is in edit and the mouse is clicked
virtual bool mouseButtonPressed(int Button, bool pressed, const SbVec3f &point,
const SbVec3f &normal, const SoPickedPoint *pp);
//@}

friend class DrawSketchHandler;

/// signals if the constraints list has changed
boost::signal<void ()> signalConstraintsChanged;
/// signals if the sketch has been set up
boost::signal<void (int type, int dofs, std::string &msg)> signalSetUp;
/// signals if the sketch has been solved
boost::signal<void (int type, float time)> signalSolved;

protected:
virtual bool setEdit(int ModNum);
virtual void unsetEdit(int ModNum);
virtual void setEditViewer(Gui::View3DInventorViewer*, int ModNum);
virtual void unsetEditViewer(Gui::View3DInventorViewer*);
/// helper to detect whether the picked point lies on the sketch
bool isPointOnSketch(const SoPickedPoint *pp) const;
/// get called by the container whenever a property has been changed
virtual void onChanged(const App::Property *prop);

/// get called if a subelement is double clicked while editing
void editDoubleClicked(void);

/// set up the edition data structure EditData
void createEditInventorNodes(void);
/// pointer to the edit data structure if the ViewProvider is in edit.
EditData *edit;
/// build up the visual of the constraints
void rebuildConstraintsVisual(void);

void setPositionText(const Base::Vector2D &Pos);
void resetPositionText(void);

// handle preselection and selection of points
void setPreselectPoint(int PreselectPoint);
void resetPreselectPoint(void);
void addSelectPoint(int SelectPoint);
void removeSelectPoint(int SelectPoint);
void clearSelectPoints(void);

// modes while sketching
SketchMode Mode;

// colors
static SbColor VertexColor;
static SbColor CurveColor;
static SbColor CurveDraftColor;
static SbColor CurveExternalColor;
static SbColor CrossColorV;
static SbColor CrossColorH;
static SbColor FullyConstrainedColor;
static SbColor ConstrDimColor;
static SbColor ConstrIcoColor;
static SbColor PreselectColor;
static SbColor SelectColor;

static SbTime prvClickTime;
static SbVec3f prvClickPoint;

float zCross;
float zLines;
float zPoints;
float zConstr;
float zHighlight;
float zText;
float zEdit;

// reference coordinates for relative operations
double xInit,yInit;
bool relative;
//jt
private:
    bool keyArcPressed;

    PolylineElementMode CurrentPolylineElementMode;
    void setPolylineElementMode(void);
};

} // namespace PartGui

—————————————————————————————————

 

 

void ViewProviderSketch::setPolylineElementMode(void)
{

    if (keyArcPressed)
        CurrentPolylineElementMode= POLYLINE_ELEMENT_TYPE_Arc;
    else
        CurrentPolylineElementMode = POLYLINE_ELEMENT_TYPE_Generic

}

 

 

http://freecad.sourcearchive.com/documentation/0.10.3247.dfsg-2/annotated.html

So I think I have the code hacked up in ViewProviderSketch to be able to specify whether whether I want an arc or a line, now the question is how to communicate that information to DrawSketchHandlerLineSet::releaseButton

 

0 DrawSketchHandlerLineSet::releaseButton CommandCreateGeo.cpp 557
1 SketcherGui::ViewProviderSketch::mouseButtonPressed ViewProviderSketch.cpp 590
2 Gui::ViewProvider::eventCallback ViewProvider.cpp 195
3 SoEventCallback::handleEvent(SoHandleEventAction*) /usr/lib/libCoin.so.60 0

Oh.. boy this looks like it’s going to get real complicated real quick..

I need to think about this..  In ViewProviderSketch I trapped whether I want to draw a line or an arc.,

I need to get info from ViewProviderSketch into DrawSketchHandlerLineSet

DrawSketchHandlerLineSet  is created here:

void CmdSketcherCreatePolyline::activated(int iMsg)
{
ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerLineSet() );
}

————————————————————————————–

class DrawSketchHandlerExternal: public DrawSketchHandler

……….

void CreateSketcherCommandsCreateGeo(void)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();

//rcCmdMgr.addCommand(new CmdSketcherCreatePoint());
rcCmdMgr.addCommand(new CmdSketcherCreateArc());
rcCmdMgr.addCommand(new CmdSketcherCreateCircle());
rcCmdMgr.addCommand(new CmdSketcherCreateLine());
rcCmdMgr.addCommand(new CmdSketcherCreatePolyline());
rcCmdMgr.addCommand(new CmdSketcherCreateRectangle());
rcCmdMgr.addCommand(new CmdSketcherCreateFillet());
//rcCmdMgr.addCommand(new CmdSketcherCreateText());
//rcCmdMgr.addCommand(new CmdSketcherCreateDraftLine());
rcCmdMgr.addCommand(new CmdSketcherTrimming());
rcCmdMgr.addCommand(new CmdSketcherExternal());
}

————————————————————–

void CmdSketcherExternal::activated(int iMsg)
{
ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerExternal());
}

————————————————————–

 

void CreateSketcherCommandsCreateGeo(void)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();

//rcCmdMgr.addCommand(new CmdSketcherCreatePoint());
rcCmdMgr.addCommand(new CmdSketcherCreateArc());
rcCmdMgr.addCommand(new CmdSketcherCreateCircle());
rcCmdMgr.addCommand(new CmdSketcherCreateLine());
rcCmdMgr.addCommand(new CmdSketcherCreatePolyline());
rcCmdMgr.addCommand(new CmdSketcherCreateRectangle());
rcCmdMgr.addCommand(new CmdSketcherCreateFillet());
//rcCmdMgr.addCommand(new CmdSketcherCreateText());
//rcCmdMgr.addCommand(new CmdSketcherCreateDraftLine());
rcCmdMgr.addCommand(new CmdSketcherTrimming());
rcCmdMgr.addCommand(new CmdSketcherExternal());
}

—————————————————————————-

void CmdSketcherExternal::activated(int iMsg)
{
ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerExternal());
}

——————————————————————————

Now it’s sort of interesting with CreateSketcherCommandsCreateGeo.

It seems that it gets instantiated in local memory by the function initSketcherGui:

————————————————————————

/* Python entry */
extern “C” {
void SketcherGuiExport initSketcherGui()
{
if (!Gui::Application::Instance) {
PyErr_SetString(PyExc_ImportError, “Cannot load Gui module in console application.”);
return;
}
try {
Base::Interpreter().runString(“import PartGui”);
Base::Interpreter().runString(“import Sketcher”);
}
catch(const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
return;
}

(void) Py_InitModule(“SketcherGui”, SketcherGui_Import_methods);   /* mod name, table ptr */
Base::Console().Log(“Loading GUI of Sketcher module… done\n”);

// instantiating the commands
CreateSketcherCommands();
CreateSketcherCommandsCreateGeo();
CreateSketcherCommandsConstraints();
CreateSketcherCommandsAlterGeo();

SketcherGui::Workbench::init();

// init objects
SketcherGui::ViewProviderSketch         ::init();
SketcherGui::ViewProviderPython         ::init();
SketcherGui::ViewProviderCustom         ::init();
SketcherGui::ViewProviderCustomPython   ::init();
SketcherGui::SoDatumLabel               ::initClass();
SketcherGui::SoZoomTranslation          ::initClass();

// add resources and reloads the translators
loadSketcherResource();
}

} // extern “C” {

————————————————————

Ok.. So now need to see where ViewProviderSketch get defined

————————————————

PROPERTY_SOURCE(SketcherGui::ViewProviderSketch, PartGui::ViewProvider2DObject)

ViewProviderSketch::ViewProviderSketch()
: edit(0),
Mode(STATUS_NONE)
—————————————————–

#define PROPERTY_SOURCE(_class_, _parentclass_) \
TYPESYSTEM_SOURCE_P(_class_);\
const App::PropertyData * _class_::getPropertyDataPtr(void){return &propertyData;} \
const App::PropertyData & _class_::getPropertyData(void) const{return propertyData;} \
App::PropertyData _class_::propertyData; \
void _class_::init(void){\
initSubclass(_class_::classTypeId, #_class_ , #_parentclass_, &(_class_::create) ); \
_class_::propertyData.parentPropertyData = _parentclass_::getPropertyDataPtr();\
}

———————————————————

/// define to implement a  subclass of Base::BaseClass
#define TYPESYSTEM_SOURCE_P(_class_) \
Base::Type _class_::getClassTypeId(void) { return _class_::classTypeId; } \
Base::Type _class_::getTypeId(void) const { return _class_::classTypeId; } \
Base::Type _class_::classTypeId = Base::Type::badType();  \
void * _class_::create(void){\
return new _class_ ();\
}

Uggggg.

So if it do the substitutions for

Base::Type SketcherGui::ViewProviderSketch::getClassTypeId(void) { return SketcherGui::ViewProviderSketch::classTypeId; } \
Base::Type SketcherGui::ViewProviderSketch::getTypeId(void) const { return SketcherGui::ViewProviderSketch::classTypeId; } \
Base::Type SketcherGui::ViewProviderSketch::classTypeId = Base::Type::badType();  \
void * SketcherGui::ViewProviderSketch::create(void){\
return new SketcherGui::ViewProviderSketch ();\
}const App::PropertyData * SketcherGui::ViewProviderSketch::getPropertyDataPtr(void){return &propertyData;} \
const App::PropertyData & SketcherGui::ViewProviderSketch::getPropertyData(void) const{return propertyData;} \
App::PropertyData SketcherGui::ViewProviderSketch::propertyData; \
void SketcherGui::ViewProviderSketch::init(void){\
initSubclass(SketcherGui::ViewProviderSketch::classTypeId, #SketcherGui::ViewProviderSketch , #PartGui::ViewProvider2DObject, &(SketcherGui::ViewProviderSketch::create) ); \
SketcherGui::ViewProviderSketch::propertyData.parentPropertyData = PartGui::ViewProvider2DObject::getPropertyDataPtr();\

================================================

 class DrawSketchHandlerLineSet: public DrawSketchHandler
{
public:
DrawSketchHandlerLineSet()
: Mode(STATUS_SEEK_First),EditCurve(2),firstPoint(-1),previousCurve(-1){}
virtual ~DrawSketchHandlerLineSet(){}
/// mode table
enum SelectMode {
STATUS_SEEK_First,      /**< enum value —-. */
STATUS_SEEK_Second,     /**< enum value —-. */
STATUS_Do,
STATUS_Close
};

virtual void activated(ViewProviderSketch *sketchgui)
{
setCursor(QPixmap(cursor_createlineset),7,7);
}

virtual void mouseMove(Base::Vector2D onSketchPos)
{
setPositionText(onSketchPos);
if (Mode==STATUS_SEEK_First) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second){
EditCurve[1] = onSketchPos;
sketchgui->drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos – EditCurve[0])) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
applyCursor();
}

virtual bool pressButton(Base::Vector2D onSketchPos)
{
if (Mode==STATUS_SEEK_First) {
// remember our first point
firstPoint = getHighestVertexIndex() + 1;
firstCurve = getHighestCurveIndex() + 1;
EditCurve[0] = onSketchPos;
Mode = STATUS_SEEK_Second;
}
else if (Mode==STATUS_SEEK_Second) {
EditCurve[1] = onSketchPos;
sketchgui->drawEdit(EditCurve);
applyCursor();
// exit on clicking exactly at the same position (e.g. double click)
if (EditCurve[1] == EditCurve[0]) {
unsetCursor();
EditCurve.clear();
resetPositionText();
sketchgui->drawEdit(EditCurve);
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
}
if (sketchgui->getPreselectPoint() == firstPoint)
Mode = STATUS_Close;
else
Mode = STATUS_Do;
}
return true;
}

virtual bool releaseButton(Base::Vector2D onSketchPos)
{
//???? NEED TO FIGURE OUT to return
        // getPolylineElementMode()  here..

if (Mode==STATUS_Do || Mode==STATUS_Close) {
// open the transaction
Gui::Command::openCommand(“add sketch wire”);
// issue the geometry
Gui::Command::doCommand(Gui::Command::Doc,”App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))”,
sketchgui->getObject()->getNameInDocument(),
EditCurve[0].fX,EditCurve[0].fY,EditCurve[1].fX,EditCurve[1].fY);

// issue the constraint
if (previousCurve != -1) {
Gui::Command::doCommand(Gui::Command::Doc,”App.ActiveDocument.%s.addConstraint(Sketcher.Constraint(‘Coincident’,%i,2,%i,1)) ”
,sketchgui->getObject()->getNameInDocument()
,previousCurve-1,previousCurve
);
}

if (Mode==STATUS_Close) {
// close the loop by constrain to the first curve point
Gui::Command::doCommand(Gui::Command::Doc,”App.ActiveDocument.%s.addConstraint(Sketcher.Constraint(‘Coincident’,%i,2,%i,1)) ”
,sketchgui->getObject()->getNameInDocument()
,previousCurve,firstCurve
);

Gui::Command::commitCommand();
Gui::Command::updateActive();

if (sugConstr2.size() > 0) {
// exclude any coincidence constraints
std::vector<AutoConstraint> sugConstr;
for (int i=0; i < sugConstr2.size(); i++) {
if (sugConstr2[i].Type != Sketcher::Coincident)
sugConstr.push_back(sugConstr2[i]);
}
createAutoConstraints(sugConstr, getHighestCurveIndex(), Sketcher::end);
sugConstr2.clear();
}

unsetCursor();
EditCurve.clear();
resetPositionText();
sketchgui->drawEdit(EditCurve);
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
}
else {
Gui::Command::commitCommand();
Gui::Command::updateActive();

// Add auto constraints
if (sugConstr1.size() > 0) {
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::start);
sugConstr1.clear();
}

if (sugConstr2.size() > 0) {
createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::end);
sugConstr2.clear();
}

//remember the vertex for the next rounds constraint…
previousCurve = getHighestCurveIndex() + 1;

// setup for the next line segment
// Use updated endPoint as autoconstraints can modify the position
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(getHighestCurveIndex());
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geom);
EditCurve[0] = Base::Vector2D(lineSeg->getEndPoint().x, lineSeg->getEndPoint().y);
}
else
EditCurve[0] = onSketchPos;

sketchgui->drawEdit(EditCurve);
applyCursor();

Mode = STATUS_SEEK_Second;
}
}
return true;
}
protected:
SelectMode Mode;
std::vector<Base::Vector2D> EditCurve;
Base::Vector2D lastPos;
int firstPoint;
int firstCurve;
int previousCurve;
std::vector<AutoConstraint> sugConstr1, sugConstr2;
};

 

Oh boy… Turn to pull off to the side of the road and ask for directions.

 

 

 

 

 

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *