Merge branch 'master' of ssh://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad

This commit is contained in:
Yorik van Havre 2012-01-08 13:49:42 -02:00
commit 671930f61e
11 changed files with 1892 additions and 1658 deletions

View File

@ -424,6 +424,16 @@ void Command::doCommand(DoCmd_Type eType,const char* sCmd,...)
free (format);
}
/// Run a App level Action
void Command::runCommand(DoCmd_Type eType,const char* sCmd)
{
if (eType == Gui)
Gui::Application::Instance->macroManager()->addLine(MacroManager::Gui,sCmd);
else
Gui::Application::Instance->macroManager()->addLine(MacroManager::Base,sCmd);
Base::Interpreter().runString(sCmd);
}
void Command::copyVisual(const char* to, const char* attr, const char* from)
{
doCommand(Gui,"Gui.ActiveDocument.%s.%s=Gui.ActiveDocument.%s.%s", to, attr, from, attr);

View File

@ -234,6 +234,7 @@ public:
static void blockCommand(bool);
/// Run a App level Action
static void doCommand(DoCmd_Type eType,const char* sCmd,...);
static void runCommand(DoCmd_Type eType,const char* sCmd);
static void copyVisual(const char* to, const char* attr, const char* from);
static void copyVisual(const char* to, const char* attr_to, const char* from, const char* attr_from);
/// import an external module only once

View File

@ -282,6 +282,7 @@ MainWindow::MainWindow(QWidget * parent, Qt::WFlags f)
d->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
d->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
d->mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation, false);
d->mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder);
QPixmap backgnd((const char**) background);
d->mdiArea->setBackground(backgnd);
setCentralWidget(d->mdiArea);

View File

@ -341,7 +341,7 @@ PyObject* Workbench::getPyObject()
return new WorkbenchPy(this);
}
void Workbench::addTaskWatcher(std::vector<Gui::TaskView::TaskWatcher*> &Watcher)
void Workbench::addTaskWatcher(const std::vector<Gui::TaskView::TaskWatcher*> &Watcher)
{
Gui::TaskView::TaskView* taskView = Control().taskPanel();
if (taskView)

View File

@ -90,7 +90,7 @@ public:
virtual void deactivated();
/// helper to add TaskWatcher to the TaskView
void addTaskWatcher(std::vector<Gui::TaskView::TaskWatcher*> &Watcher);
void addTaskWatcher(const std::vector<Gui::TaskView::TaskWatcher*> &Watcher);
/// remove the added TaskWatcher
void removeTaskWatcher(void);

View File

@ -592,35 +592,22 @@ class svgHandler(xml.sax.ContentHandler):
path = []
point = []
command = None
#elif (len(point)==6) and (command=="cubic"):
elif (command=="cubic") and (((smooth==False) and (len(point)==6)) or (smooth==True and (len(point)==4))) :
if smooth:
if relative:
currentvec = lastvec.add(Vector(point[2],-point[3],0))
pole2 = lastvec.add(Vector(point[0],-point[1],0))
else:
currentvec = Vector(point[2],-point[3],0)
pole2 = Vector(point[0],-point[1],0)
if lastpole is not None and lastpole[0]=='cubic':
pole1 = lastvec.sub(lastpole[1]).add(lastvec)
else:
pole1 = lastvec
else: #not smooth
if relative:
currentvec = lastvec.add(Vector(point[4],-point[5],0))
pole1 = lastvec.add(Vector(point[0],-point[1],0))
pole2 = lastvec.add(Vector(point[2],-point[3],0))
else:
currentvec = Vector(point[4],-point[5],0)
pole1 = Vector(point[0],-point[1],0)
pole2 = Vector(point[2],-point[3],0)
elif (len(point)==6) and (command=="curve"):
if relative:
currentvec = lastvec.add(Vector(point[4],-point[5],0))
pole1 = lastvec.add(Vector(point[0],-point[1],0))
pole2 = lastvec.add(Vector(point[2],-point[3],0))
else:
currentvec = Vector(point[4],-point[5],0)
pole1 = Vector(point[0],-point[1],0)
pole2 = Vector(point[2],-point[3],0)
if not fcvec.equals(currentvec,lastvec):
mainv = currentvec.sub(lastvec)
pole1v = lastvec.add(pole1)
pole2v = currentvec.add(pole2)
print "cubic curve data:",mainv.normalize(),pole1v.normalize(),pole2v.normalize()
if pole1.distanceToLine(lastvec,currentvec) < 10**(-1*Draft.precision()) and pole2.distanceToLine(lastvec,currentvec) < 10**(-1*Draft.precision()):
print "curve data:",mainv.normalize(),pole1v.normalize(),pole2v.normalize()
if (round(mainv.getAngle(pole1v),Draft.precision()) in [0,round(math.pi,Draft.precision())]) \
and (round(mainv.getAngle(pole2v),Draft.precision()) in [0,round(math.pi,Draft.precision())]):
print "straight segment"
seg = Part.Line(lastvec,currentvec).toShape()
else:

View File

@ -249,7 +249,7 @@ CmdDrawingNewView::CmdDrawingNewView()
void CmdDrawingNewView::activated(int iMsg)
{
std::vector<App::DocumentObject*> shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId());
if (shapes.size() != 1) {
if (shapes.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select a Part object."));
return;
@ -262,19 +262,19 @@ void CmdDrawingNewView::activated(int iMsg)
return;
}
std::string FeatName = getUniqueObjectName("View");
std::string PageName = pages.front()->getNameInDocument();
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
openCommand("Create view");
doCommand(Doc,"App.activeDocument().addObject('Drawing::FeatureViewPart','%s')",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",FeatName.c_str(),shapes.front()->getNameInDocument());
doCommand(Doc,"App.activeDocument().%s.Direction = (0.0,0.0,1.0)",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.X = 10.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Y = 10.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Scale = 1.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());
for (std::vector<App::DocumentObject*>::iterator it = shapes.begin(); it != shapes.end(); ++it) {
std::string FeatName = getUniqueObjectName("View");
doCommand(Doc,"App.activeDocument().addObject('Drawing::FeatureViewPart','%s')",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",FeatName.c_str(),(*it)->getNameInDocument());
doCommand(Doc,"App.activeDocument().%s.Direction = (0.0,0.0,1.0)",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.X = 10.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Y = 10.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Scale = 1.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());
}
updateActive();
commitCommand();
}

View File

@ -23,6 +23,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QString>
# include <QDir>
# include <QFileInfo>
@ -295,17 +296,18 @@ void CmdPartCommon::activated(int iMsg)
std::string FeatName = getUniqueObjectName("Common");
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::string ObjectBuf;
std::stringstream str;
std::vector<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Shapes = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
ObjectBuf += std::string("App.activeDocument().") + it->FeatName + ",";
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
}
ObjectBuf.erase(--ObjectBuf.end());
str << "]";
openCommand("Common");
doCommand(Doc,"App.activeDocument().addObject(\"Part::MultiCommon\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Shapes = [%s]",FeatName.c_str(),ObjectBuf.c_str());
runCommand(Doc,str.str().c_str());
for (std::vector<std::string>::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it)
doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str());
copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str());
@ -348,17 +350,18 @@ void CmdPartFuse::activated(int iMsg)
std::string FeatName = getUniqueObjectName("Fusion");
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::string ObjectBuf;
std::stringstream str;
std::vector<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Shapes = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
ObjectBuf += std::string("App.activeDocument().") + it->FeatName + ",";
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
}
ObjectBuf.erase(--ObjectBuf.end());
str << "]";
openCommand("Fusion");
doCommand(Doc,"App.activeDocument().addObject(\"Part::MultiFuse\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Shapes = [%s]",FeatName.c_str(),ObjectBuf.c_str());
runCommand(Doc,str.str().c_str());
for (std::vector<std::string>::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it)
doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str());
copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str());

View File

@ -24,15 +24,22 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Python.h>
#include <gp_Ax1.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <GC_MakeArcOfCircle.hxx>
#include <Geom_Circle.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Handle_Geom_Circle.hxx>
#include <Handle_Geom_TrimmedCurve.hxx>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/events/SoMouseButtonEvent.h>
#endif
#include <Base/Interpreter.h>
#include <Base/Rotation.h>
#include <Base/Tools.h>
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
@ -47,6 +54,130 @@
using namespace PartGui;
namespace PartGui {
const char* gce_ErrorStatusText(gce_ErrorType et)
{
switch (et)
{
case gce_Done:
return "Construction was successful";
case gce_ConfusedPoints:
return "Two points are coincident";
case gce_NegativeRadius:
return "Radius value is negative";
case gce_ColinearPoints:
return "Three points are collinear";
case gce_IntersectionError:
return "Intersection cannot be computed";
case gce_NullAxis:
return "Axis is undefined";
case gce_NullAngle:
return "Angle value is invalid (usually null)";
case gce_NullRadius:
return "Radius is null";
case gce_InvertAxis:
return "Axis value is invalid";
case gce_BadAngle:
return "Angle value is invalid";
case gce_InvertRadius:
return "Radius value is incorrect (usually with respect to another radius)";
case gce_NullFocusLength:
return "Focal distance is null";
case gce_NullVector:
return "Vector is null";
case gce_BadEquation:
return "Coefficients are incorrect (applies to the equation of a geometric object)";
default:
return "Creation of geometry failed";
}
}
void Picker::createPrimitive(QWidget* widget, const QString& descr, Gui::Document* doc)
{
try {
App::Document* app = doc->getDocument();
QString cmd = this->command(app);
// Execute the Python block
doc->openCommand(descr.toUtf8());
Gui::Command::doCommand(Gui::Command::Doc, (const char*)cmd.toAscii());
doc->commitCommand();
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
Gui::Command::doCommand(Gui::Command::Gui, "Gui.SendMsgToActiveView(\"ViewFit\")");
}
catch (const Base::Exception& e) {
QMessageBox::warning(widget, descr, QString::fromLatin1(e.what()));
}
}
QString Picker::toPlacement(const gp_Ax2& axis) const
{
gp_Dir dir = axis.Direction();
gp_Pnt pnt = gp_Pnt(0.0,0.0,0.0);
gp_Ax3 ax3(pnt, dir, axis.XDirection());
gp_Trsf Trf;
Trf.SetTransformation(ax3);
Trf.Invert();
gp_XYZ theAxis(0,0,1);
Standard_Real theAngle = 0.0;
Trf.GetRotation(theAxis,theAngle);
Base::Rotation rot(Base::convertTo<Base::Vector3d>(theAxis), theAngle);
gp_Pnt loc = axis.Location();
return QString::fromAscii("Base.Placement(Base.Vector(%1,%2,%3),Base.Rotation(%4,%5,%6,%7))")
.arg(loc.X(),0,'f',2)
.arg(loc.Y(),0,'f',2)
.arg(loc.Z(),0,'f',2)
.arg(rot[0],0,'f',2)
.arg(rot[1],0,'f',2)
.arg(rot[2],0,'f',2)
.arg(rot[3],0,'f',2);
}
class CircleFromThreePoints : public Picker
{
public:
CircleFromThreePoints() : Picker()
{
}
bool pickedPoint(const SoPickedPoint * point)
{
SbVec3f pnt = point->getPoint();
points.push_back(gp_Pnt(pnt[0],pnt[1],pnt[2]));
return points.size() == 3;
}
QString command(App::Document* doc) const
{
GC_MakeArcOfCircle arc(points[0], points[1], points[2]);
if (!arc.IsDone())
throw Base::Exception(gce_ErrorStatusText(arc.Status()));
Handle_Geom_TrimmedCurve trim = arc.Value();
Handle_Geom_Circle circle = Handle_Geom_Circle::DownCast(trim->BasisCurve());
QString name = QString::fromAscii(doc->getUniqueObjectName("Circle").c_str());
return QString::fromAscii(
"App.ActiveDocument.addObject(\"Part::Circle\",\"%1\")\n"
"App.ActiveDocument.%1.Radius=%2\n"
"App.ActiveDocument.%1.Angle0=%3\n"
"App.ActiveDocument.%1.Angle1=%4\n"
"App.ActiveDocument.%1.Placement=%5\n")
.arg(name)
.arg(circle->Radius(),0,'f',2)
.arg(Base::toDegrees(trim->FirstParameter()),0,'f',2)
.arg(Base::toDegrees(trim->LastParameter ()),0,'f',2)
.arg(toPlacement(circle->Position()));
}
private:
std::vector<gp_Pnt> points;
};
}
/* TRANSLATOR PartGui::DlgPrimitives */
DlgPrimitives::DlgPrimitives(QWidget* parent)
@ -136,6 +267,66 @@ DlgPrimitives::~DlgPrimitives()
{
}
void DlgPrimitives::pickCallback(void * ud, SoEventCallback * n)
{
const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent*>(n->getEvent());
Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
// Mark all incoming mouse button events as handled, especially, to deactivate the selection node
n->setHandled();
if (mbe->getButton() == SoMouseButtonEvent::BUTTON1) {
if (mbe->getState() == SoButtonEvent::DOWN) {
const SoPickedPoint * point = n->getPickedPoint();
if (point) {
Picker* pick = reinterpret_cast<Picker*>(ud);
if (pick->pickedPoint(point)) {
pick->loop.exit(0);
}
}
}
}
else if (mbe->getButton() == SoMouseButtonEvent::BUTTON2) {
if (mbe->getState() == SoButtonEvent::UP) {
Picker* pick = reinterpret_cast<Picker*>(ud);
pick->loop.exit(1);
}
}
}
void DlgPrimitives::executeCallback(Picker* p)
{
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (!doc) {
return;
}
Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(doc->getActiveView());
if (view) {
Gui::View3DInventorViewer* viewer = view->getViewer();
if (!viewer->isEditing()) {
viewer->setEditing(true);
viewer->setRedirectToSceneGraph(true);
viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, p);
this->setDisabled(true);
int ret = p->loop.exec();
this->setEnabled(true);
viewer->setEditing(false);
viewer->setRedirectToSceneGraph(false);
viewer->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, p);
if (ret == 0) {
p->createPrimitive(this, ui.comboBox1->currentText(), doc);
}
}
}
}
void DlgPrimitives::on_buttonCircleFromThreePoints_clicked()
{
CircleFromThreePoints pp;
executeCallback(&pp);
}
void DlgPrimitives::createPrimitive(const QString& placement)
{
try {
@ -384,9 +575,6 @@ void DlgPrimitives::createPrimitive(const QString& placement)
Location::Location(QWidget* parent)
{
ui.setupUi(this);
connect(ui.viewPositionButton, SIGNAL(clicked()),
this, SLOT(on_viewPositionButton_clicked()));
}
Location::~Location()

View File

@ -23,14 +23,36 @@
#ifndef PARTGUI_DLGPRIMITIVES_H
#define PARTGUI_DLGPRIMITIVES_H
#include <QEventLoop>
#include <QPointer>
#include <Gui/TaskView/TaskDialog.h>
#include "ui_DlgPrimitives.h"
#include "ui_Location.h"
class gp_Ax2;
class SoEventCallback;
namespace App { class Document; }
namespace Gui { class Document; }
namespace PartGui {
class Picker
{
public:
Picker()
{
}
virtual ~Picker()
{
}
virtual bool pickedPoint(const SoPickedPoint * point) = 0;
virtual QString command(App::Document*) const = 0;
void createPrimitive(QWidget* widget, const QString&, Gui::Document*);
QString toPlacement(const gp_Ax2&) const;
QEventLoop loop;
};
class DlgPrimitives : public QWidget
{
@ -41,6 +63,13 @@ public:
~DlgPrimitives();
void createPrimitive(const QString&);
private Q_SLOTS:
void on_buttonCircleFromThreePoints_clicked();
private:
static void pickCallback(void * ud, SoEventCallback * n);
void executeCallback(Picker*);
private:
Ui_DlgPrimitives ui;
};

File diff suppressed because it is too large Load Diff