+ fix design flaw to reduce side effects

This commit is contained in:
wmayer
2016-06-09 19:58:22 +02:00
parent cb434e517b
commit c02c90adb2
9 changed files with 152 additions and 157 deletions

View File

@@ -28,6 +28,7 @@
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Precision.hxx>
#include <gp_Trsf.hxx>
#include <BRep_Tool.hxx>
@@ -57,7 +58,7 @@ BSplineSurf::BSplineSurf() : BSurf()
App::DocumentObjectExecReturn *BSplineSurf::execute(void)
{
correcteInvalidFillType();
//Begin Construction
try{
std::vector<Handle_Geom_BSplineCurve> crvs;
crvs.reserve(4);
@@ -103,17 +104,19 @@ App::DocumentObjectExecReturn *BSplineSurf::execute(void)
GeomFill_FillingStyle fstyle = getFillingStyle();
GeomFill_BSplineCurves aSurfBuilder; //Create Surface Builder
if(edgeCount==2) {
std::size_t edgeCount = crvs.size();
if (edgeCount==2) {
aSurfBuilder.Init(crvs[0], crvs[1], fstyle);
}
else if(edgeCount==3) {
else if (edgeCount==3) {
aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle);
}
else if(edgeCount==4) {
else if (edgeCount==4) {
aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle);
}
//createFace(aSurfBuilder.Surface());
createFace(aSurfBuilder.Surface());
return App::DocumentObject::StdReturn;
}

View File

@@ -44,6 +44,11 @@
using namespace Surface;
ShapeValidator::ShapeValidator()
{
initValidator();
}
void ShapeValidator::initValidator(void)
{
willBezier = willBSpline = false;
@@ -181,7 +186,7 @@ void BSurf::getWire(TopoDS_Wire& aWire)
Standard_Failure::Raise("Only 2-4 curves are allowed");
}
initValidator();
ShapeValidator validator;
for(std::size_t i = 0; i < boundary.size(); i++)
{
App::PropertyLinkSubList::SubSet set = boundary[i];
@@ -190,7 +195,7 @@ void BSurf::getWire(TopoDS_Wire& aWire)
for (auto jt: set.second) {
const Part::TopoShape &ts = static_cast<Part::Feature*>(set.first)->Shape.getShape();
checkAndAdd(ts, jt.c_str(), &aWD);
validator.checkAndAdd(ts, jt.c_str(), &aWD);
}
}
else {
@@ -198,8 +203,7 @@ void BSurf::getWire(TopoDS_Wire& aWire)
}
}
if(edgeCount < 2 || edgeCount > 4)
{
if(validator.numEdges() < 2 || validator.numEdges() > 4) {
Standard_Failure::Raise("Only 2-4 curves are allowed");
}

View File

@@ -44,13 +44,25 @@ protected:
bool willBSpline;
int edgeCount;
public:
ShapeValidator();
void initValidator(void);
void checkEdge(const TopoDS_Shape& shape);
void checkAndAdd(const TopoDS_Shape &shape, Handle(ShapeExtend_WireData) *aWD = NULL);
void checkAndAdd(const Part::TopoShape &ts, const char *subName, Handle(ShapeExtend_WireData) *aWire = NULL);
bool isBezier() const {
return willBezier;
}
bool isBSpline() const {
return willBSpline;
}
int numEdges() const {
return edgeCount;
}
};
class BSurf : public Part::Feature, public ShapeValidator
class BSurf : public Part::Feature
{
PROPERTY_HEADER(Surface::BSurf);

View File

@@ -28,6 +28,7 @@
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Precision.hxx>
#include <gp_Trsf.hxx>
#include <BRep_Tool.hxx>
@@ -84,17 +85,19 @@ App::DocumentObjectExecReturn *BezSurf::execute(void)
GeomFill_FillingStyle fstyle = getFillingStyle();
GeomFill_BezierCurves aSurfBuilder; //Create Surface Builder
std::size_t edgeCount = crvs.size();
if (edgeCount == 2) {
aSurfBuilder.Init(crvs[0], crvs[1], fstyle);
}
else if(edgeCount == 3) {
else if (edgeCount == 3) {
aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle);
}
else if(edgeCount == 4) {
else if (edgeCount == 4) {
aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle);
}
//createFace(aSurfBuilder.Surface());
createFace(aSurfBuilder.Surface());
return App::DocumentObject::StdReturn;
}

View File

@@ -41,8 +41,6 @@ using namespace Surface;
PROPERTY_SOURCE(Surface::Cut, Part::Feature)
//Initial values
Cut::Cut()
{
ADD_PROPERTY(ShapeList,(0,"TopoDS_Shape"));
@@ -59,44 +57,32 @@ short Cut::mustExecute() const
App::DocumentObjectExecReturn *Cut::execute(void)
{
#if 0
//Perform error checking
//Begin Construction
try{
if((aShapeList.getSize()>2) || (aShapeList.getSize()<2)){
try {
std::vector<App::DocumentObject*> shapes = ShapeList.getValues();
if (shapes.size() != 2){
return new App::DocumentObjectExecReturn("Two shapes must be entered at a time for a cut operation");
}
//Initialize variables for first toposhape from document object
Part::TopoShape ts1;
TopoDS_Shape sub1;
App::PropertyLinkSubList::SubSet set1 = aShapeList[0];
//Initialize variables for second toposhape from document object
Part::TopoShape ts2;
TopoDS_Shape sub2;
App::PropertyLinkSubList::SubSet set2 = aShapeList[1];
//Get first toposhape
printf("Get first toposhape\n");
if(set1.obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts1 = static_cast<Part::Feature*>(set1.obj)->Shape.getShape(); //Part::TopoShape 1
if (shapes[0]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts1 = static_cast<Part::Feature*>(shapes[0])->Shape.getShape(); //Part::TopoShape 1
}
else {
return new App::DocumentObjectExecReturn("Shape1 not from Part::Feature");
}
else{return new App::DocumentObjectExecReturn("Shape1 not from Part::Feature");}
//Get second toposhape
printf("Get second toposhape\n");
if(set2.obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts2 = static_cast<Part::Feature*>(set2.obj)->Shape.getShape();
if (shapes[1]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts2 = static_cast<Part::Feature*>(shapes[1])->Shape.getShape();
}
else {
return new App::DocumentObjectExecReturn("Shape2 not from Part::Feature");
}
else{return new App::DocumentObjectExecReturn("Shape2 not from Part::Feature");}
//Cut Shape1 by Shape2
TopoDS_Shape aCutShape;
@@ -106,14 +92,12 @@ App::DocumentObjectExecReturn *Cut::execute(void)
if (aCutShape.IsNull()){
return new App::DocumentObjectExecReturn("Resulting shape is null");
}
this->Shape.setValue(aCutShape);
return 0;
} //End Try
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
return new App::DocumentObjectExecReturn(e->GetMessageString());
} //End Catch
#endif
return 0;
}
}

View File

@@ -1,3 +1,26 @@
/***************************************************************************
* Copyright (c) 2015 Balázs Bámer *
* *
* 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 *
* *
***************************************************************************/
#ifndef SURFACE_FILLTYPE_H
#define SURFACE_FILLTYPE_H

View File

@@ -37,7 +37,6 @@
using namespace SurfaceGui;
//#undef CS_FUTURE // multi-threading causes some problems
PROPERTY_SOURCE(SurfaceGui::ViewProviderBSurf, PartGui::ViewProviderPart)
@@ -45,22 +44,21 @@ namespace SurfaceGui {
bool ViewProviderBSurf::setEdit(int ModNum)
{
// When double-clicking on the item for this sketch the
// object unsets and sets its edit mode without closing
// the task panel
// When double-clicking on the item for this sketch the
// object unsets and sets its edit mode without closing
// the task panel
Surface::BSurf* obj = static_cast<Surface::BSurf*>(this->getObject());
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
TaskBSurf* tDlg = qobject_cast<TaskBSurf*>(dlg);
// start the edit dialog
if(dlg)
{
// start the edit dialog
if(dlg) {
tDlg->setEditedObject(obj);
Gui::Control().showDialog(tDlg);
}
else
{
else {
Gui::Control().showDialog(new TaskBSurf(this, obj));
}
return true;
@@ -145,28 +143,26 @@ void BSurf::accept()
void BSurf::reject()
{
if(oldFillType == InvalidStyle)
{
if (oldFillType == InvalidStyle) {
Gui::Command::abortCommand();
}
else
{
else {
// if the object fill type was changed, reset the old one
if(editedObject->FillType.getValue() != oldFillType)
{
if (editedObject->FillType.getValue() != oldFillType) {
editedObject->FillType.setValue(oldFillType);
}
Gui::Command::commitCommand();
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
}
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
}
void BSurf::apply()
{
// apply the change only if it is a real change
if(editedObject->FillType.getValue() != fillType)
{
if (editedObject->FillType.getValue() != fillType) {
editedObject->FillType.setValue(fillType);
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
}

View File

@@ -20,17 +20,13 @@
* *
***************************************************************************/
// Part::CrossSections.*
#ifndef SURFACE_GUI_BSURF_H
#define SURFACE_GUI_BSURF_H
#include "PreCompiled.h"
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
#include <Base/BoundBox.h>
#include <Mod/Surface/FillType.h>
#include <Mod/Surface/App/FillType.h>
#include <Mod/Part/Gui/ViewProvider.h>
#include <Mod/Surface/App/FeatureBSurf.h>
@@ -39,7 +35,7 @@ namespace SurfaceGui
class Ui_DlgBSurf;
class SurfaceGuiExport ViewProviderBSurf : public PartGui::ViewProviderPart
class ViewProviderBSurf : public PartGui::ViewProviderPart
{
PROPERTY_HEADER(SurfaceGui::ViewProviderBSurf);
public:
@@ -51,6 +47,7 @@ namespace SurfaceGui
class BSurf : public QWidget
{
Q_OBJECT
protected:
filltype_t fillType, oldFillType;
Surface::BSurf* editedObject;

View File

@@ -25,6 +25,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <sstream>
#include <QApplication>
#include <QString>
#include <QDir>
#include <QFileInfo>
@@ -78,7 +79,6 @@ CmdSurfaceFilling::CmdSurfaceFilling()
sWhatsThis = QT_TR_NOOP("Surface Filling function");
sStatusTip = QT_TR_NOOP("Surface Filling function");
sPixmap = "Filling.svg";
sAccel = "CTRL+H";
}
void CmdSurfaceFilling::activated(int iMsg)
@@ -149,22 +149,10 @@ void CmdSurfaceCut::activated(int iMsg)
//===========================================================================
// Bezier and BSpline surfaces
//===========================================================================
//DEF_STD_CMD_A(CmdSurfaceBSurf);
class CmdSurfaceBSurf : public Gui::Command, public Surface::ShapeValidator
{
public:
CmdSurfaceBSurf();
virtual ~CmdSurfaceBSurf(){}
virtual const char* className() const
{ return "CmdSurfaceBSurf"; }
protected:
virtual bool isActive(void);
void createSurface(const char *surfaceNamePrefix, const char *commandName, const char *pythonAddCommand);
void showError(const char *msg);
virtual void activated(int iMsg);
};
DEF_STD_CMD_A(CmdSurfaceBSurf);
CmdSurfaceBSurf::CmdSurfaceBSurf() : Command("Surface_BSurf")
CmdSurfaceBSurf::CmdSurfaceBSurf()
: Command("Surface_BSurf")
{
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
@@ -178,120 +166,105 @@ CmdSurfaceBSurf::CmdSurfaceBSurf() : Command("Surface_BSurf")
bool CmdSurfaceBSurf::isActive(void)
{
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
long size = Sel.size();
if(size < 1 || size > 4) {
std::size_t size = Sel.size();
if (size < 1 || size > 4) {
return false;
}
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it)
{
if(!((*it).pObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) {
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it) {
if (!((*it).pObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) {
return false;
}
}
return true;
}
void CmdSurfaceBSurf::createSurface(const char *surfaceNamePrefix, const char *commandName, const char *pythonAddCommand)
{
std::string FeatName = getUniqueObjectName(surfaceNamePrefix);
std::stringstream bspListCmd;
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
bspListCmd << "FreeCAD.ActiveDocument.ActiveObject.BoundaryList = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it)
{
Gui::SelectionSingleton::SelObj selObj = *it;
Part::TopoShape ts = static_cast<Part::Feature*>(selObj.pObject)->Shape.getShape();
bspListCmd << "(App.activeDocument()." << selObj.FeatName;
// if it is wire, add as wire
if((!ts._Shape.IsNull()) && ts._Shape.ShapeType() == TopAbs_WIRE)
{
bspListCmd << ", \'Wire1\'),";
}
else
{
const char *subName = selObj.SubName;
if(subName != NULL && *subName != 0)
{
bspListCmd << ", \'" << subName << "\'),";
}
else
{
bspListCmd << ", \'Edge1\'),";
}
}
}
bspListCmd << "]";
openCommand(commandName);
doCommand(Doc, pythonAddCommand, FeatName.c_str());
// invalid fill type meaning the surface is just created and cancel should delete it
doCommand(Doc, "FreeCAD.ActiveDocument.ActiveObject.FillType=0");
doCommand(Doc, bspListCmd.str().c_str());
doCommand(Doc, "Gui.ActiveDocument.setEdit('%s',0)", FeatName.c_str());
updateActive();
}
void CmdSurfaceBSurf::showError(const char *msg)
{
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Error"),
QObject::tr(msg));
}
void CmdSurfaceBSurf::activated(int iMsg)
{
initValidator();
Surface::ShapeValidator validator;
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
if (Sel.size() > 4) {
showError("Too many selected objects.");
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Surface_BSurf", "Error"),
qApp->translate("Surface_BSurf", "Too many selected objects."));
return;
}
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it)
{
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it) {
Gui::SelectionSingleton::SelObj selObj = *it;
if(!(selObj.pObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) {
showError("Selected object is not a feature.");
if (!(selObj.pObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) {
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Surface_BSurf", "Error"),
qApp->translate("Surface_BSurf", "Selected object is not a feature."));
return;
}
Part::TopoShape ts = static_cast<Part::Feature*>(selObj.pObject)->Shape.getShape();
try {
checkAndAdd(ts, selObj.SubName);
validator.checkAndAdd(ts, selObj.SubName);
}
catch(Standard_Failure sf) {
showError(sf.GetMessageString());
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Surface_BSurf", "Error"),
QString::fromLatin1(sf.GetMessageString()));
return;
}
}
switch(edgeCount) {
switch(validator.numEdges()) {
case 2:
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Warning"),
QObject::tr("Surfaces with two edges may fail for some fill types."));
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Surface_BSurf", "Warning"),
qApp->translate("Surface_BSurf", "Surfaces with two edges may fail for some fill types."));
break;
case 3: // no message
case 4:
break;
default:
showError("This tool requires 2, 3 or 4 curves.");
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Surface_BSurf", "Error"),
qApp->translate("Surface_BSurf", "This tool requires 2, 3 or 4 curves."));
return;
}
// check wich was activated and perfom and clearing the flag
if(willBezier)
{
createSurface("BezierSurface", "Create Bezier surface", "FreeCAD.ActiveDocument.addObject(\"Surface::BezSurf\",\"%s\")");
willBezier = false;
std::stringstream out;
std::vector<Gui::SelectionObject> SelEx = Gui::Selection().getSelectionEx();
for (std::vector<Gui::SelectionObject>::iterator it = SelEx.begin(); it != SelEx.end(); ++it) {
out << it->getAsPropertyLinkSubString() << ",";
}
if(willBSpline)
{
createSurface("BSplineSurface", "Create BSpline surface", "FreeCAD.ActiveDocument.addObject(\"Surface::BSplineSurf\",\"%s\")");
willBSpline = false;
std::string linklist = out.str();
// check which was activated
if (validator.isBezier()) {
std::string FeatName = getUniqueObjectName("BezierSurface");
openCommand("Create Bezier surface");
doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::BezSurf\",\"%s\")", FeatName.c_str());
// invalid fill type meaning the surface is just created and cancel should delete it
doCommand(Doc, "App.ActiveDocument.ActiveObject.FillType=0");
doCommand(Doc, "App.ActiveDocument.ActiveObject.BoundaryList = [%s]", linklist.c_str());
doCommand(Doc, "Gui.ActiveDocument.setEdit('%s',0)", FeatName.c_str());
updateActive();
}
if (validator.isBSpline()) {
std::string FeatName = getUniqueObjectName("BSplineSurface");
openCommand("Create BSpline surface");
doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::BSplineSurf\",\"%s\")", FeatName.c_str());
// invalid fill type meaning the surface is just created and cancel should delete it
doCommand(Doc, "App.ActiveDocument.ActiveObject.FillType=0");
doCommand(Doc, "App.ActiveDocument.ActiveObject.BoundaryList = [%s]", linklist.c_str());
doCommand(Doc, "Gui.ActiveDocument.setEdit('%s',0)", FeatName.c_str());
updateActive();
}
}
void CreateSurfaceCommands(void)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
/* rcCmdMgr.addCommand(new CmdSurfaceFilling());
/* rcCmdMgr.addCommand(new CmdSurfaceFilling());
rcCmdMgr.addCommand(new CmdSurfaceCut());*/
rcCmdMgr.addCommand(new CmdSurfaceBSurf());
}