Sketcher: add support for points as construction geometry

This commit is contained in:
logari81 2012-07-08 12:01:07 +02:00
parent 093f1d1af0
commit 714908d3e9
9 changed files with 195 additions and 51 deletions

View File

@ -256,6 +256,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "Sketcher_ViewSketch"
<< "Sketcher_MapSketch"
<< "Separator"
<< "Sketcher_CreatePoint"
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"
@ -484,6 +485,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "Sketcher_NewSketch"
<< "Sketcher_LeaveSketch"
<< "Separator"
<< "Sketcher_CreatePoint"
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"

View File

@ -125,7 +125,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
Gui::MenuItem* geom = new Gui::MenuItem();
geom->setCommand("Sketcher geometries");
*geom /*<< "Sketcher_CreatePoint"*/
*geom << "Sketcher_CreatePoint"
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"
@ -194,7 +194,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
part = new Gui::ToolBarItem(root);
part->setCommand("Sketcher geometries");
*part /*<< "Sketcher_CreatePoint" */
*part << "Sketcher_CreatePoint"
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"

View File

@ -150,7 +150,11 @@ const char* nameByType(Sketch::GeoType type)
int Sketch::addGeometry(const Part::Geometry *geo, bool fixed)
{
if (geo->getTypeId() == GeomLineSegment::getClassTypeId()) { // add a line
if (geo->getTypeId() == GeomPoint::getClassTypeId()) { // add a point
const GeomPoint *point = dynamic_cast<const GeomPoint*>(geo);
// create the definition struct for that geom
return addPoint(*point, fixed);
} else if (geo->getTypeId() == GeomLineSegment::getClassTypeId()) { // add a line
const GeomLineSegment *lineSeg = dynamic_cast<const GeomLineSegment*>(geo);
// create the definition struct for that geom
return addLineSegment(*lineSeg, fixed);
@ -174,24 +178,30 @@ void Sketch::addGeometry(const std::vector<Part::Geometry *> &geo, bool fixed)
addGeometry(*it, fixed);
}
int Sketch::addPoint(const Base::Vector3d &newPoint, bool fixed)
int Sketch::addPoint(const Part::GeomPoint &point, bool fixed)
{
std::vector<double *> &params = fixed ? FixParameters : Parameters;
// create our own copy
GeomPoint *p = static_cast<GeomPoint*>(point.clone());
// points in a sketch are always construction elements
p->Construction = true;
// create the definition struct for that geom
GeoDef def;
def.geo = 0;
def.geo = p;
def.type = Point;
// set the parameter for the solver
params.push_back(new double(newPoint.x));
params.push_back(new double(newPoint.y));
params.push_back(new double(p->getPoint().x));
params.push_back(new double(p->getPoint().y));
// set the points for later constraints
GCS::Point p1;
p1.x = params[params.size()-2];
p1.y = params[params.size()-1];
def.startPointId = Points.size();
def.endPointId = Points.size();
def.midPointId = Points.size();
Points.push_back(p1);
// store complete set
@ -393,7 +403,10 @@ Py::Tuple Sketch::getPyGeometry(void) const
Py::Tuple tuple(Geoms.size());
int i=0;
for (std::vector<GeoDef>::const_iterator it=Geoms.begin(); it != Geoms.end(); ++it, i++) {
if (it->type == Line) {
if (it->type == Point) {
Base::Vector3d temp(*(Points[it->startPointId].x),*(Points[it->startPointId].y),0);
tuple[i] = Py::asObject(new VectorPy(temp));
} else if (it->type == Line) {
GeomLineSegment *lineSeg = dynamic_cast<GeomLineSegment*>(it->geo->clone());
tuple[i] = Py::asObject(new LinePy(lineSeg));
} else if (it->type == Arc) {
@ -402,9 +415,6 @@ Py::Tuple Sketch::getPyGeometry(void) const
} else if (it->type == Circle) {
GeomCircle *circle = dynamic_cast<GeomCircle*>(it->geo->clone());
tuple[i] = Py::asObject(new CirclePy(circle));
} else if (it->type == Point) {
Base::Vector3d temp(*(Points[Geoms[i].startPointId].x),*(Points[Geoms[i].startPointId].y),0);
tuple[i] = Py::asObject(new VectorPy(temp));
} else if (it->type == Ellipse) {
GeomEllipse *ellipse = dynamic_cast<GeomEllipse*>(it->geo->clone());
tuple[i] = Py::asObject(new EllipsePy(ellipse));
@ -1517,7 +1527,13 @@ bool Sketch::updateGeometry()
int i=0;
for (std::vector<GeoDef>::const_iterator it=Geoms.begin(); it != Geoms.end(); ++it, i++) {
try {
if (it->type == Line) {
if (it->type == Point) {
GeomPoint *point = dynamic_cast<GeomPoint*>(it->geo);
point->setPoint(Vector3d(*Points[it->startPointId].x,
*Points[it->startPointId].y,
0.0)
);
} else if (it->type == Line) {
GeomLineSegment *lineSeg = dynamic_cast<GeomLineSegment*>(it->geo);
lineSeg->setPoints(Vector3d(*Lines[it->index].p1.x,
*Lines[it->index].p1.y,
@ -1653,7 +1669,18 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
return -1;
}
if (Geoms[geoId].type == Line) {
if (Geoms[geoId].type == Point) {
if (pos == start) {
GCS::Point &point = Points[Geoms[geoId].startPointId];
GCS::Point p0;
MoveParameters.resize(2); // px,py
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *point.x;
*p0.y = *point.y;
GCSsys.addConstraintP2PCoincident(p0,point,-1);
}
} else if (Geoms[geoId].type == Line) {
if (pos == start || pos == end) {
MoveParameters.resize(2); // x,y
GCS::Point p0;
@ -1771,6 +1798,11 @@ int Sketch::movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool rela
MoveParameters[i] = InitParameters[i] + toPoint.x;
MoveParameters[i+1] = InitParameters[i+1] + toPoint.y;
}
} else if (Geoms[geoId].type == Point) {
if (pos == start) {
MoveParameters[0] = toPoint.x;
MoveParameters[1] = toPoint.y;
}
} else if (Geoms[geoId].type == Line) {
if (pos == start || pos == end) {
MoveParameters[0] = toPoint.x;

View File

@ -108,7 +108,7 @@ public:
/// add dedicated geometry
//@{
/// add a point
int addPoint(const Base::Vector3d &point, bool fixed=false);
int addPoint(const Part::GeomPoint &point, bool fixed=false);
/// add an infinite line
int addLine(const Part::GeomLineSegment &line, bool fixed=false);
/// add a line segment

View File

@ -75,6 +75,7 @@ SketchObject::SketchObject()
VLine->Construction = true;
ExternalGeo.push_back(HLine);
ExternalGeo.push_back(VLine);
rebuildVertexIndex();
}
SketchObject::~SketchObject()
@ -1328,7 +1329,10 @@ void SketchObject::rebuildVertexIndex(void)
const std::vector< Part::Geometry * > geometry = getCompleteGeometry();
for (std::vector< Part::Geometry * >::const_iterator it = geometry.begin();
it != geometry.end(); ++it) {
if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
if ((*it)->getTypeId() == Part::GeomPoint::getClassTypeId()) {
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(start);
} else if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(start);
VertexId2GeoId.push_back(i);

View File

@ -1242,6 +1242,102 @@ bool CmdSketcherCreateCircle::isActive(void)
// ======================================================================================
/* XPM */
static const char *cursor_createpoint[]={
"32 32 3 1",
"+ c white",
"# c red",
". c None",
"......+.........................",
"......+.........................",
"......+.........................",
"......+.........................",
"......+.........................",
"................................",
"+++++...+++++...................",
"................................",
"......+.........................",
"......+.........................",
"......+.........................",
"......+.........................",
"......+.........................",
"...............+++++++..........",
"..............++.....++.........",
".............+.........+........",
"............++.........++.......",
"...........++...........++......",
"...........+.............+......",
"...........+.............+......",
"...........+.............+......",
"...........+.............+......",
"...........+.............+......",
"...........+.............+......",
"...........++...........++......",
"............++.........++.......",
".............+.........+........",
"..............++.....++.........",
"...............+++++++..........",
"................................",
"................................",
"................................"};
class DrawSketchHandlerPoint: public DrawSketchHandler
{
public:
DrawSketchHandlerPoint() : selectionDone(false) {}
virtual ~DrawSketchHandlerPoint() {}
virtual void activated(ViewProviderSketch *sketchgui)
{
setCursor(QPixmap(cursor_createpoint),7,7);
}
virtual void mouseMove(Base::Vector2D onSketchPos)
{
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr, onSketchPos, Base::Vector2D(0.f,0.f))) {
renderSuggestConstraintsCursor(sugConstr);
}
applyCursor();
}
virtual bool pressButton(Base::Vector2D onSketchPos)
{
EditPoint = onSketchPos;
selectionDone = true;
return true;
}
virtual bool releaseButton(Base::Vector2D onSketchPos)
{
if (selectionDone){
unsetCursor();
resetPositionText();
Gui::Command::openCommand("Add sketch point");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Point(App.Vector(%f,%f,0)))",
sketchgui->getObject()->getNameInDocument(),
EditPoint.fX,EditPoint.fY);
Gui::Command::commitCommand();
Gui::Command::updateActive();
// add auto constraints for the line segment start
if (sugConstr.size() > 0) {
createAutoConstraints(sugConstr, getHighestCurveIndex(), Sketcher::start);
sugConstr.clear();
}
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
}
return true;
}
protected:
bool selectionDone;
Base::Vector2D EditPoint;
std::vector<AutoConstraint> sugConstr;
};
DEF_STD_CMD_A(CmdSketcherCreatePoint);
CmdSketcherCreatePoint::CmdSketcherCreatePoint()
@ -1259,11 +1355,12 @@ CmdSketcherCreatePoint::CmdSketcherCreatePoint()
void CmdSketcherCreatePoint::activated(int iMsg)
{
ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerPoint());
}
bool CmdSketcherCreatePoint::isActive(void)
{
return false;
return isCreateGeoActive(getActiveGuiDocument());
}
// ======================================================================================
@ -1882,7 +1979,7 @@ void CreateSketcherCommandsCreateGeo(void)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
//rcCmdMgr.addCommand(new CmdSketcherCreatePoint());
rcCmdMgr.addCommand(new CmdSketcherCreatePoint());
rcCmdMgr.addCommand(new CmdSketcherCreateArc());
rcCmdMgr.addCommand(new CmdSketcherCreateCircle());
rcCmdMgr.addCommand(new CmdSketcherCreateLine());

View File

@ -137,7 +137,7 @@ struct EditData {
CurvesMaterials(0),
PointsCoordinate(0),
CurvesCoordinate(0),
CurveSet(0),
CurveSet(0), EditCurveSet(0), RootCrossSet(0),
PointSet(0)
{}
@ -159,12 +159,13 @@ struct EditData {
bool blockedPreselection;
bool FullyConstrained;
// pointer to the Solver
// instance of the solver
Sketcher::Sketch ActSketch;
// container to track our own selected parts
std::set<int> SelPointSet;
std::set<int> SelCurvSet; // also holds cross axes at -1 and -2
std::set<int> SelConstraintSet;
std::vector<int> CurvIdToGeoId; // conversion of SoLineSet index to GeoId
// helper data structure for the constraint rendering
std::vector<ConstraintType> vConstrType;
@ -615,16 +616,16 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe
Gui::MenuItem *geom = new Gui::MenuItem();
geom->setCommand("Sketcher geoms");
*geom /*<< "Sketcher_CreatePoint"*/
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"
<< "Sketcher_CreatePolyline"
<< "Sketcher_CreateRectangle"
<< "Sketcher_CreateFillet"
<< "Sketcher_Trimming"
<< "Sketcher_External"
<< "Sketcher_ToggleConstruction"
*geom << "Sketcher_CreatePoint"
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"
<< "Sketcher_CreatePolyline"
<< "Sketcher_CreateRectangle"
<< "Sketcher_CreateFillet"
<< "Sketcher_Trimming"
<< "Sketcher_External"
<< "Sketcher_ToggleConstruction"
/*<< "Sketcher_CreateText"*/
/*<< "Sketcher_CreateDraftLine"*/;
@ -753,8 +754,8 @@ bool ViewProviderSketch::mouseMove(const SbVec3f &point, const SbVec3f &normal,
bool preselectChanged;
if (Mode!=STATUS_SKETCH_DragPoint && Mode!=STATUS_SKETCH_DragCurve &&
Mode!=STATUS_SKETCH_DragConstraint) {
int PtIndex,CurvIndex,ConstrIndex,CrossIndex;
preselectChanged = detectPreselection(pp,PtIndex,CurvIndex,ConstrIndex,CrossIndex);
int PtIndex,GeoIndex,ConstrIndex,CrossIndex;
preselectChanged = detectPreselection(pp,PtIndex,GeoIndex,ConstrIndex,CrossIndex);
}
switch (Mode) {
@ -1184,12 +1185,12 @@ void ViewProviderSketch::onSelectionChanged(const Gui::SelectionChanges& msg)
}
}
bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtIndex, int &CurvIndex, int &ConstrIndex, int &CrossIndex)
bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtIndex, int &GeoIndex, int &ConstrIndex, int &CrossIndex)
{
assert(edit);
PtIndex = -1;
CurvIndex = -1; // valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
GeoIndex = -1; // valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
CrossIndex = -1;
ConstrIndex = -1;
@ -1213,12 +1214,8 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
const SoDetail *curve_detail = Point->getDetail(edit->CurveSet);
if (curve_detail && curve_detail->getTypeId() == SoLineDetail::getClassTypeId()) {
// get the index
CurvIndex = static_cast<const SoLineDetail *>(curve_detail)->getLineIndex();
int maxGeoId = getSketchObject()->getHighestCurveIndex();
if (CurvIndex > maxGeoId) { // hit on external geometry
int extGeoCount = getSketchObject()->getExternalGeometryCount();
CurvIndex = -extGeoCount + (CurvIndex - maxGeoId - 1);
}
int CurvIndex = static_cast<const SoLineDetail *>(curve_detail)->getLineIndex();
GeoIndex = edit->CurvIdToGeoId[CurvIndex];
}
// checking for a hit in the cross
} else if (tail == edit->RootCrossSet) {
@ -1259,12 +1256,12 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
edit->sketchHandler->applyCursor();
return true;
}
} else if (CurvIndex != -1 && CurvIndex != edit->PreselectCurve) { // if a new curve is hit
} else if (GeoIndex != -1 && GeoIndex != edit->PreselectCurve) { // if a new curve is hit
std::stringstream ss;
if (CurvIndex >= 0)
ss << "Edge" << CurvIndex;
if (GeoIndex >= 0)
ss << "Edge" << GeoIndex;
else // external geometry
ss << "ExternalEdge" << -CurvIndex - 3; // convert index start from -3 to 0
ss << "ExternalEdge" << -GeoIndex - 3; // convert index start from -3 to 0
bool accepted =
Gui::Selection().setPreselect(getSketchObject()->getDocument()->getName()
,getSketchObject()->getNameInDocument()
@ -1275,7 +1272,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
edit->blockedPreselection = !accepted;
if (accepted) {
resetPreselectPoint();
edit->PreselectCurve = CurvIndex;
edit->PreselectCurve = GeoIndex;
edit->PreselectCross = -1;
edit->PreselectConstraint = -1;
if (edit->sketchHandler)
@ -1326,7 +1323,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
edit->sketchHandler->applyCursor();
return true;
}
} else if ((PtIndex == -1 && CurvIndex == -1 && CrossIndex == -1 && ConstrIndex == -1) &&
} else if ((PtIndex == -1 && GeoIndex == -1 && CrossIndex == -1 && ConstrIndex == -1) &&
(edit->PreselectPoint != -1 || edit->PreselectCurve != -1 || edit->PreselectCross != -1
|| edit->PreselectConstraint != -1 || edit->blockedPreselection)) {
// we have just left a preselection
@ -1384,7 +1381,7 @@ void ViewProviderSketch::updateColor(void)
int intGeoCount = getSketchObject()->getHighestCurveIndex() + 1;
int extGeoCount = getSketchObject()->getExternalGeometryCount();
for (int i=0; i < CurvNum; i++) {
int GeoId = (i < intGeoCount) ? i : -(extGeoCount - (i - intGeoCount));
int GeoId = edit->CurvIdToGeoId[i];
if (edit->SelCurvSet.find(GeoId) != edit->SelCurvSet.end())
color[i] = SelectColor;
else if (edit->PreselectCurve == GeoId)
@ -1629,8 +1626,16 @@ void ViewProviderSketch::draw(bool temp)
assert(int(geomlist->size()) == extGeoCount + intGeoCount);
assert(int(geomlist->size()) >= 2);
for (std::vector<Part::Geometry *>::const_iterator it = geomlist->begin(); it != geomlist->end()-2; ++it) {
if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { // add a line
edit->CurvIdToGeoId.clear();
int GeoId = 0;
for (std::vector<Part::Geometry *>::const_iterator it = geomlist->begin(); it != geomlist->end()-2; ++it, GeoId++) {
if (GeoId >= intGeoCount)
GeoId = -extGeoCount;
if ((*it)->getTypeId() == Part::GeomPoint::getClassTypeId()) { // add a point
const Part::GeomPoint *point = dynamic_cast<const Part::GeomPoint *>(*it);
Points.push_back(point->getPoint());
}
else if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { // add a line
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(*it);
// create the definition struct for that geom
Coords.push_back(lineSeg->getStartPoint());
@ -1638,6 +1643,7 @@ void ViewProviderSketch::draw(bool temp)
Points.push_back(lineSeg->getStartPoint());
Points.push_back(lineSeg->getEndPoint());
Index.push_back(2);
edit->CurvIdToGeoId.push_back(GeoId);
}
else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) { // add a circle
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(*it);
@ -1655,6 +1661,7 @@ void ViewProviderSketch::draw(bool temp)
Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
Index.push_back(countSegments+1);
edit->CurvIdToGeoId.push_back(GeoId);
Points.push_back(center);
}
else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { // add an arc
@ -1685,6 +1692,7 @@ void ViewProviderSketch::draw(bool temp)
Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
Index.push_back(countSegments+1);
edit->CurvIdToGeoId.push_back(GeoId);
Points.push_back(center);
Points.push_back(start);
Points.push_back(end);
@ -1718,6 +1726,7 @@ void ViewProviderSketch::draw(bool temp)
}
Index.push_back(countSegments+1);
edit->CurvIdToGeoId.push_back(GeoId);
}
else {
;

View File

@ -126,7 +126,7 @@ public:
/// 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);
bool detectPreselection(const SoPickedPoint *Point, int &PtIndex,int &GeoIndex, 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

View File

@ -60,7 +60,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
sketch->setCommand("S&ketch");
Gui::MenuItem* geom = new Gui::MenuItem();
geom->setCommand("Sketcher geometries");
*geom /*<< "Sketcher_CreatePoint"*/
*geom << "Sketcher_CreatePoint"
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"
@ -112,7 +112,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
part = new Gui::ToolBarItem(root);
part->setCommand("Sketcher geometries");
*part /*<< "Sketcher_CreatePoint" */
*part << "Sketcher_CreatePoint"
<< "Sketcher_CreateArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_CreateLine"