00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <Standard_math.hxx>
00028 # include <Inventor/nodes/SoTranslation.h>
00029 # include <Inventor/nodes/SoText2.h>
00030 # include <Inventor/nodes/SoFont.h>
00031 # include <QPainter>
00032 #endif
00033
00035 #include <Base/Console.h>
00036 #include <Base/Exception.h>
00037 #include <Base/Interpreter.h>
00038 #include <Gui/Application.h>
00039 #include <Gui/BitmapFactory.h>
00040 #include <Gui/Command.h>
00041 #include <Gui/Document.h>
00042 #include <Gui/Macro.h>
00043 #include <Gui/MainWindow.h>
00044 #include <Gui/View3DInventorViewer.h>
00045 #include <Gui/View3DInventor.h>
00046
00047 #include <Mod/Part/App/Geometry.h>
00048 #include <Mod/Sketcher/App/SketchObject.h>
00049
00050 #include "DrawSketchHandler.h"
00051 #include "ViewProviderSketch.h"
00052
00053
00054 using namespace SketcherGui;
00055 using namespace Sketcher;
00056
00057
00058
00059
00060
00061 DrawSketchHandler::DrawSketchHandler()
00062 : sketchgui(0)
00063 {
00064
00065 }
00066
00067 DrawSketchHandler::~DrawSketchHandler()
00068 {
00069
00070 }
00071
00072 void DrawSketchHandler::quit(void)
00073 {
00074 assert(sketchgui);
00075 sketchgui->drawEdit(std::vector<Base::Vector2D>());
00076 resetPositionText();
00077
00078 unsetCursor();
00079 sketchgui->purgeHandler();
00080 }
00081
00082
00083
00084
00085 Sketcher::SketchObject* DrawSketchHandler::getObject(void)
00086 {
00087 return dynamic_cast<Sketcher::SketchObject*>(sketchgui->getObject());
00088 }
00089
00090 int DrawSketchHandler::getHighestVertexIndex(void)
00091 {
00092 return getObject()->getHighestVertexIndex();
00093 }
00094
00095 int DrawSketchHandler::getHighestCurveIndex(void)
00096 {
00097 return getObject()->getHighestCurveIndex();
00098 }
00099
00100 void DrawSketchHandler::setCursor(const QPixmap &p,int x,int y)
00101 {
00102 Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
00103 if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
00104 Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
00105
00106 oldCursor = viewer->getWidget()->cursor();
00107 QCursor cursor(p, x, y);
00108 actCursor = cursor;
00109
00110 viewer->getWidget()->setCursor(cursor);
00111 }
00112 }
00113
00114 void DrawSketchHandler::applyCursor(void)
00115 {
00116 applyCursor(actCursor);
00117 }
00118
00119 void DrawSketchHandler::applyCursor(QCursor &newCursor)
00120 {
00121 Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
00122 if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
00123 Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
00124 viewer->getWidget()->setCursor(newCursor);
00125 }
00126 }
00127
00128 void DrawSketchHandler::unsetCursor(void)
00129 {
00130 Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
00131 if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
00132 Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
00133 viewer->getWidget()->setCursor(oldCursor);
00134 }
00135 }
00136
00137 int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint> &suggestedConstraints,
00138 const Base::Vector2D& Pos, const Base::Vector2D& Dir, Type type)
00139 {
00140 suggestedConstraints.clear();
00141
00142 if (!sketchgui->Autoconstraints.getValue())
00143 return 0;
00144
00145
00146
00147 if (type == VERTEX && sketchgui->getPreselectPoint() != -1) {
00148 AutoConstraint coincident;
00149 coincident.Type = Sketcher::Coincident;
00150 coincident.Index = sketchgui->getPreselectPoint();
00151 suggestedConstraints.push_back(coincident);
00152 }
00153 else if (type == CURVE && sketchgui->getPreselectPoint() != -1) {
00154 AutoConstraint pointOnObject;
00155 pointOnObject.Type = Sketcher::PointOnObject;
00156 pointOnObject.Index = sketchgui->getPreselectPoint();
00157 suggestedConstraints.push_back(pointOnObject);
00158 }
00159 else if (type == VERTEX && sketchgui->getPreselectCurve() != -1) {
00160 AutoConstraint pointOnObject;
00161 pointOnObject.Type = Sketcher::PointOnObject;
00162 pointOnObject.Index = sketchgui->getPreselectCurve();
00163 suggestedConstraints.push_back(pointOnObject);
00164 }
00165 else if (type == CURVE && sketchgui->getPreselectCurve() != -1) {
00166 AutoConstraint tangent;
00167 tangent.Type = Sketcher::Tangent;
00168 tangent.Index = sketchgui->getPreselectCurve();
00169 suggestedConstraints.push_back(tangent);
00170 }
00171
00172 if (Dir.Length() < 1)
00173
00174 return suggestedConstraints.size();
00175
00176
00177
00178
00179 const double angleDev = 2;
00180 const double angleDevRad = angleDev * M_PI / 180.;
00181
00182 double angle = std::abs(atan2(Dir.fY, Dir.fX));
00183 if (angle < angleDevRad || (M_PI - angle) < angleDevRad ) {
00184
00185 AutoConstraint horConstr;
00186 horConstr.Index = -1;
00187 horConstr.Type = Horizontal;
00188 suggestedConstraints.push_back(horConstr);
00189 }
00190 else if (std::abs(angle - M_PI_2) < angleDevRad) {
00191
00192 AutoConstraint vertConstr;
00193 vertConstr.Index = -1;
00194 vertConstr.Type = Vertical;
00195 suggestedConstraints.push_back(vertConstr);
00196 }
00197
00198
00199
00200 const float tangDeviation = 2.;
00201
00202 int tangId = -1;
00203 float smlTangDist = 0;
00204
00205
00206 const std::vector<Part::Geometry *> geomlist = getObject()->Geometry.getValues();
00207
00208
00209 int i = 0;
00210 for (std::vector<Part::Geometry *>::const_iterator it = geomlist.begin(); it != geomlist.end(); ++it, i++) {
00211
00212 if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) {
00213 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>((*it));
00214
00215 Base::Vector3d center = circle->getCenter();
00216 Base::Vector3d tmpPos(Pos.fX, Pos.fY, 0.f);
00217
00218 float radius = (float) circle->getRadius();
00219
00220 Base::Vector3d projPnt(0.f, 0.f, 0.f);
00221 projPnt = projPnt.ProjToLine(center - tmpPos, Base::Vector3d(Dir.fX, Dir.fY));
00222 float projDist = projPnt.Length();
00223
00224 if ( (projDist < radius + tangDeviation ) && (projDist > radius - tangDeviation))
00225 {
00226
00227 if (tangId == -1 || projDist< smlTangDist)
00228 {
00229 tangId = i;
00230 smlTangDist = projDist;
00231 }
00232 }
00233
00234 } else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
00235 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>((*it));
00236
00237 Base::Vector3d center = arc->getCenter();
00238 double radius = arc->getRadius();
00239
00240 Base::Vector3d projPnt(0.f, 0.f, 0.f);
00241 Base::Vector3d tmpPos(Pos.fX, Pos.fY, 0.f);
00242
00243 projPnt = projPnt.ProjToLine(center - tmpPos, Base::Vector3d(Dir.fX, Dir.fY));
00244 float projDist = projPnt.Length();
00245
00246 if ( projDist < radius + tangDeviation && projDist > radius - tangDeviation) {
00247 double startAngle, endAngle;
00248 arc->getRange(startAngle, endAngle);
00249
00250 projPnt += center;
00251 double angle = atan2(projPnt.y, projPnt.x);
00252
00253
00254 if ((angle > startAngle && angle < endAngle) &&
00255 (tangId == -1 || projDist < smlTangDist) ) {
00256 tangId = i;
00257 smlTangDist = projDist;
00258 }
00259 }
00260 }
00261 }
00262
00263 if (tangId != -1) {
00264
00265 AutoConstraint tangConstr;
00266 tangConstr.Index = tangId;
00267 tangConstr.Type = Tangent;
00268 suggestedConstraints.push_back(tangConstr);
00269 }
00270
00271 return suggestedConstraints.size();
00272 }
00273
00274 void DrawSketchHandler::createAutoConstraints(const std::vector<AutoConstraint> &autoConstrs,
00275 int geoId, Sketcher::PointPos pointPos)
00276 {
00277 if (!sketchgui->Autoconstraints.getValue())
00278 return;
00279
00280 if (autoConstrs.size() > 0) {
00281
00282 Gui::Command::openCommand("Add auto constraints");
00283
00284
00285 std::vector<AutoConstraint>::const_iterator it = autoConstrs.begin();
00286 for (; it != autoConstrs.end(); ++it) {
00287 switch (it->Type)
00288 {
00289 case Sketcher::Coincident: {
00290 if (pointPos == Sketcher::none)
00291 continue;
00292
00293 Sketcher::PointPos pointPos2;
00294 int geoId2;
00295 sketchgui->getSketchObject()->getGeoVertexIndex(it->Index, geoId2, pointPos2);
00296
00297 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,%i,%i,%i)) "
00298 ,sketchgui->getObject()->getNameInDocument()
00299 ,geoId, pointPos, geoId2, pointPos2
00300 );
00301 } break;
00302 case Sketcher::PointOnObject: {
00303 int index = it->Index;
00304 if (pointPos == Sketcher::none) {
00305
00306 index = geoId;
00307 sketchgui->getSketchObject()->getGeoVertexIndex(it->Index, geoId, pointPos);
00308 }
00309
00310 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%i,%i,%i)) "
00311 ,sketchgui->getObject()->getNameInDocument()
00312 ,geoId, pointPos, index
00313 );
00314 } break;
00315 case Sketcher::Horizontal: {
00316 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Horizontal',%i)) "
00317 ,sketchgui->getObject()->getNameInDocument()
00318 ,geoId
00319 );
00320 } break;
00321 case Sketcher::Vertical: {
00322 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Vertical',%i)) "
00323 ,sketchgui->getObject()->getNameInDocument()
00324 ,geoId
00325 );
00326 } break;
00327 case Sketcher::Tangent: {
00328 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%i, %i)) "
00329 ,sketchgui->getObject()->getNameInDocument()
00330 ,geoId, it->Index
00331 );
00332 } break;
00333 }
00334
00335 Gui::Command::commitCommand();
00336 Gui::Command::updateActive();
00337 }
00338 }
00339 }
00340
00341 void DrawSketchHandler::renderSuggestConstraintsCursor(std::vector<AutoConstraint> &suggestedConstraints)
00342 {
00343
00344 int iconSize = 16;
00345
00346
00347 QPixmap baseIcon = actCursor.pixmap();
00348 QPixmap newIcon(baseIcon.width() + suggestedConstraints.size() * iconSize,
00349 baseIcon.height());
00350 newIcon.fill(Qt::transparent);
00351
00352 QPainter qp;
00353 qp.begin(&newIcon);
00354
00355 qp.drawPixmap(0,0, baseIcon);
00356
00357
00358 std::vector<AutoConstraint>::iterator it=suggestedConstraints.begin();
00359 int i = 0;
00360 for (; it != suggestedConstraints.end(); ++it, i++) {
00361 QString iconType;
00362 switch (it->Type)
00363 {
00364 case Horizontal:
00365 iconType = QString::fromAscii("Constraint_Horizontal");
00366 break;
00367 case Vertical:
00368 iconType = QString::fromAscii("Constraint_Vertical");
00369 break;
00370 case Coincident:
00371 iconType = QString::fromAscii("Constraint_PointOnPoint");
00372 break;
00373 case PointOnObject:
00374 iconType = QString::fromAscii("Constraint_PointOnObject");
00375 break;
00376 case Tangent:
00377 iconType = QString::fromAscii("Constraint_Tangent");
00378 break;
00379 }
00380
00381 QPixmap icon = Gui::BitmapFactory().pixmap(iconType.toAscii()).scaledToWidth(iconSize);
00382 qp.drawPixmap(QPoint(baseIcon.width() + i * iconSize, baseIcon.height() - iconSize), icon);
00383 }
00384
00385 qp.end();
00386
00387
00388 QPoint p=actCursor.hotSpot();
00389 QCursor newCursor(newIcon, p.x(), p.y());
00390 applyCursor(newCursor);
00391 }
00392
00393 void DrawSketchHandler::setPositionText(const Base::Vector2D &Pos)
00394 {
00395 sketchgui->setPositionText(Pos);
00396 }
00397
00398 void DrawSketchHandler::resetPositionText(void)
00399 {
00400 sketchgui->resetPositionText();
00401 }