Merge branch 'logari81/PartDesign' of git://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad

This commit is contained in:
jrheinlaender
2012-09-11 12:03:48 +04:30
59 changed files with 12951 additions and 575 deletions

View File

@@ -41,8 +41,13 @@
#include "FeatureFace.h"
#include "FeatureSubtractive.h"
#include "FeatureAdditive.h"
#include "FeatureTransformed.h"
#include "FeatureMirrored.h"
#include "FeatureLinearPattern.h"
#include "FeaturePolarPattern.h"
#include "FeatureScaled.h"
#include "FeatureMultiTransform.h"
#include "FeatureHole.h"
#include "FeaturePatternRectangular.h"
extern struct PyMethodDef PartDesign_methods[];
@@ -76,7 +81,12 @@ void PartDesignExport initPartDesign()
PartDesign::SketchBased ::init();
PartDesign::Subtractive ::init();
PartDesign::Additive ::init();
PartDesign::PatternRectangular ::init();
PartDesign::Transformed ::init();
PartDesign::Mirrored ::init();
PartDesign::LinearPattern ::init();
PartDesign::PolarPattern ::init();
PartDesign::Scaled ::init();
PartDesign::MultiTransform ::init();
PartDesign::Hole ::init();
PartDesign::Body ::init();
PartDesign::Pad ::init();

View File

@@ -23,13 +23,27 @@ set(PartDesign_LIBS
SET(Features_SRCS
Feature.cpp
Feature.h
FeaturePatternRectangular.h
FeaturePatternRectangular.cpp
Body.cpp
Body.h
)
SOURCE_GROUP("Features" FILES ${Features_SRCS})
SET(FeaturesTransformed_SRCS
FeatureTransformed.h
FeatureTransformed.cpp
FeatureMirrored.h
FeatureMirrored.cpp
FeatureLinearPattern.h
FeatureLinearPattern.cpp
FeaturePolarPattern.h
FeaturePolarPattern.cpp
FeatureScaled.h
FeatureScaled.cpp
FeatureMultiTransform.h
FeatureMultiTransform.cpp
)
SOURCE_GROUP("FeaturesTransformed" FILES ${FeaturesTransformed_SRCS})
SET(FeaturesDressUp_SRCS
FeatureDressUp.cpp
FeatureDressUp.h
@@ -73,6 +87,7 @@ SOURCE_GROUP("Module" FILES ${Module_SRCS})
SET(PartDesign_SRCS
${Features_SRCS}
${FeaturesTransformed_SRCS}
${FeaturesSketchBased_SRCS}
${FeaturesDressUp_SRCS}
${Module_SRCS}

View File

@@ -26,6 +26,9 @@
# include <Standard_Failure.hxx>
# include <TopoDS_Solid.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <BRep_Tool.hxx>
# include <gp_Pnt.hxx>
#endif
@@ -55,4 +58,19 @@ TopoDS_Shape Feature::getSolid(const TopoDS_Shape& shape) const
return TopoDS_Shape();
}
const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f) const
{
if (!f.Infinite()) {
TopExp_Explorer exp;
exp.Init(f, TopAbs_VERTEX);
if (exp.More())
return BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
// Else try the other method
}
// TODO: Other method, e.g. intersect X,Y,Z axis with the (unlimited?) face?
// Or get a "corner" point if the face is limited?
throw Base::Exception("getPointFromFace(): Not implemented yet for this case");
}
}

View File

@@ -27,6 +27,8 @@
#include <App/PropertyStandard.h>
#include <Mod/Part/App/PartFeature.h>
class gp_Pnt;
/// Base class of all additive features in PartDesign
namespace PartDesign
@@ -48,6 +50,10 @@ protected:
* Get a solid of the given shape. If no solid is found an exception is raised.
*/
TopoDS_Shape getSolid(const TopoDS_Shape&) const;
/// Grab any point from the given face
const gp_Pnt getPointFromFace(const TopoDS_Face& f) const;
};
} //namespace PartDesign

View File

@@ -0,0 +1,169 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <gp_Pln.hxx>
# include <gp_Dir.hxx>
# include <gp_Ax1.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <BRepAdaptor_Surface.hxx>
#endif
#include "FeatureLinearPattern.h"
#include <Mod/Part/App/TopoShape.h>
#include <Base/Axis.h>
using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::LinearPattern, PartDesign::Transformed)
LinearPattern::LinearPattern()
{
ADD_PROPERTY_TYPE(Direction,(0),"LinearPattern",(App::PropertyType)(App::Prop_None),"Direction");
ADD_PROPERTY(StdDirection,(""));
ADD_PROPERTY(Reversed,(0));
ADD_PROPERTY(Length,(100.0));
ADD_PROPERTY(Occurrences,(3));
}
short LinearPattern::mustExecute() const
{
if (Direction.isTouched() ||
StdDirection.isTouched() ||
Reversed.isTouched() ||
Length.isTouched() ||
Occurrences.isTouched())
return 1;
return Transformed::mustExecute();
}
const std::list<gp_Trsf> LinearPattern::getTransformations(const std::vector<App::DocumentObject*>)
{
std::string stdDirection = StdDirection.getValue();
float distance = Length.getValue();
if (distance < Precision::Confusion())
throw Base::Exception("Pattern length too small");
int occurrences = Occurrences.getValue();
if (occurrences < 2)
throw Base::Exception("At least two occurrences required");
bool reversed = Reversed.getValue();
gp_Dir dir;
double offset = distance / (occurrences - 1);
if (!stdDirection.empty()) {
// Note: The placement code commented out below had the defect of working always on the
// absolute X,Y,Z direction, not on the relative coordinate system of the Body feature.
// It requires positionBySupport() to be called in Transformed::Execute() AFTER
// the call to getTransformations()
// New code thanks to logari81
if (stdDirection == "X") {
//dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0));
dir = gp_Dir(1,0,0);
} else if (stdDirection == "Y") {
//dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0));
dir = gp_Dir(0,1,0);
} else if(stdDirection == "Z") {
//dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,0,1));
dir = gp_Dir(0,0,1);
} else {
throw Base::Exception("Invalid direction (must be X, Y or Z)");
}
} else {
App::DocumentObject* refObject = Direction.getValue();
if (refObject == NULL)
throw Base::Exception("No direction specified");
if (!refObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
throw Base::Exception("Direction reference must be edge or face of a feature");
std::vector<std::string> subStrings = Direction.getSubValues();
if (subStrings.empty() || subStrings[0].empty())
throw Base::Exception("No direction reference specified");
Part::Feature* refFeature = static_cast<Part::Feature*>(refObject);
Part::TopoShape refShape = refFeature->Shape.getShape();
TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str());
if (ref.ShapeType() == TopAbs_FACE) {
TopoDS_Face refFace = TopoDS::Face(ref);
if (refFace.IsNull())
throw Base::Exception("Failed to extract direction plane");
BRepAdaptor_Surface adapt(refFace);
if (adapt.GetType() != GeomAbs_Plane)
throw Base::Exception("Direction face must be planar");
dir = adapt.Plane().Axis().Direction();
//gp_Dir d = adapt.Plane().Axis().Direction();
//dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(d.X(), d.Y(), d.Z()));
} else if (ref.ShapeType() == TopAbs_EDGE) {
TopoDS_Edge refEdge = TopoDS::Edge(ref);
if (refEdge.IsNull())
throw Base::Exception("Failed to extract direction edge");
BRepAdaptor_Curve adapt(refEdge);
if (adapt.GetType() != GeomAbs_Line)
throw Base::Exception("Direction edge must be a straight line");
//gp_Dir d = adapt.Line().Direction();
//dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(d.X(), d.Y(), d.Z()));
dir = adapt.Line().Direction();
} else {
throw Base::Exception("Direction reference must be edge or face");
}
TopLoc_Location invObjLoc = this->getLocation().Inverted();
dir.Transform(invObjLoc.Transformation());
}
// get the support placement
// TODO: Check for NULL pointer
/*Part::Feature* supportFeature = static_cast<Part::Feature*>(originals.front());
if (supportFeature == NULL)
throw Base::Exception("Cannot work on invalid support shape");
Base::Placement supportPlacement = supportFeature->Placement.getValue();
dir *= supportPlacement;
gp_Vec direction(dir.getDirection().x, dir.getDirection().y, dir.getDirection().z);*/
gp_Vec direction(dir.X(), dir.Y(), dir.Z());
if (reversed)
direction.Reverse();
// Note: The original feature is NOT included in the list of transformations! Therefore
// we start with occurrence number 1, not number 0
std::list<gp_Trsf> transformations;
gp_Trsf trans;
transformations.push_back(trans); // identity transformation
for (int i = 1; i < occurrences; i++) {
trans.SetTranslation(direction * i * offset);
transformations.push_back(trans);
}
return transformations;
}
}

View File

@@ -0,0 +1,74 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTDESIGN_FeatureLinearPattern_H
#define PARTDESIGN_FeatureLinearPattern_H
#include <App/PropertyStandard.h>
#include "FeatureTransformed.h"
namespace PartDesign
{
class PartDesignExport LinearPattern : public PartDesign::Transformed
{
PROPERTY_HEADER(PartDesign::LinearPattern);
public:
LinearPattern();
App::PropertyLinkSub Direction;
App::PropertyString StdDirection;
App::PropertyBool Reversed;
App::PropertyFloat Length;
App::PropertyInteger Occurrences;
/** @name methods override feature */
//@{
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "PartDesignGui::ViewProviderLinearPattern";
}
//@}
/** Create transformations
* Returns a list of (Occurrences - 1) transformations since the first, untransformed instance
* is not counted. Each transformation will move the shape it is applied to by the distance
* (Length / (Occurrences - 1)) so that the transformations will cover the total Length.
* If StdDirection is "X", "Y" or "Z" then the transformation direction will be parallel to the
* corresponding axis
* If Direction contains a feature and a face name, then the transformation direction will be
* the normal of the given face, which must be planar. If it contains an edge name, then the
* transformation direction will be parallel to the given edge, which must be linear
* If Reversed is true, the direction of transformation will be opposite
*/
const std::list<gp_Trsf> getTransformations(const std::vector<App::DocumentObject*> );
};
} //namespace PartDesign
#endif // PARTDESIGN_FeatureLinearPattern_H

View File

@@ -0,0 +1,120 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <gp_Pln.hxx>
# include <gp_Dir.hxx>
# include <BRepAdaptor_Surface.hxx>
#endif
#include "FeatureMirrored.h"
#include <Mod/Part/App/TopoShape.h>
using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::Mirrored, PartDesign::Transformed)
Mirrored::Mirrored()
{
ADD_PROPERTY_TYPE(MirrorPlane,(0),"Mirrored",(App::PropertyType)(App::Prop_None),"Mirror plane");
ADD_PROPERTY(StdMirrorPlane,(""));
}
short Mirrored::mustExecute() const
{
if (MirrorPlane.isTouched() ||
StdMirrorPlane.isTouched())
return 1;
return Transformed::mustExecute();
}
const std::list<gp_Trsf> Mirrored::getTransformations(const std::vector<App::DocumentObject*>)
{
App::DocumentObject* ref = MirrorPlane.getValue();
std::vector<std::string> subStrings = MirrorPlane.getSubValues();
std::string stdPlane = StdMirrorPlane.getValue();
gp_Pnt p;
gp_Dir d;
if (!stdPlane.empty()) {
p = gp_Pnt(0,0,0);
if (stdPlane == "XY") {
d = gp_Dir(0,0,1);
} else if (stdPlane == "XZ") {
d = gp_Dir(0,1,0);
} else if(stdPlane == "YZ") {
d = gp_Dir(1,0,0);
} else {
throw Base::Exception("Invalid mirror plane (must be XY, XZ or YZ)");
}
} else {
if (ref == NULL)
throw Base::Exception("No mirror plane selected");
if (!ref->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
throw Base::Exception("Mirror plane must be face of a feature");
Part::TopoShape baseShape = static_cast<Part::Feature*>(ref)->Shape.getShape();
if (subStrings.empty() || subStrings[0].empty())
throw Base::Exception("No mirror plane defined");
// TODO: Check for multiple mirror planes?
TopoDS_Face face = TopoDS::Face(baseShape.getSubShape(subStrings[0].c_str()));
if (face.IsNull())
throw Base::Exception("Failed to extract mirror plane");
BRepAdaptor_Surface adapt(face);
if (adapt.GetType() != GeomAbs_Plane)
throw Base::Exception("Mirror face must be planar");
p = getPointFromFace(face);
d = adapt.Plane().Axis().Direction();
TopLoc_Location invObjLoc = this->getLocation().Inverted();
p.Transform(invObjLoc.Transformation());
d.Transform(invObjLoc.Transformation());
}
// get the support placement
// TODO: Check for NULL pointer
/*Part::Feature* supportFeature = static_cast<Part::Feature*>(originals.front());
if (supportFeature == NULL)
throw Base::Exception("Cannot work on invalid support shape");
Base::Placement supportPlacement = supportFeature->Placement.getValue();
ax *= supportPlacement;
gp_Ax2 mirrorAxis(gp_Pnt(ax.getBase().x, ax.getBase().y, ax.getBase().z), gp_Dir(ax.getDirection().x, ax.getDirection().y, ax.getDirection().z));*/
gp_Ax2 mirrorAxis(p, d);
std::list<gp_Trsf> transformations;
gp_Trsf trans;
transformations.push_back(trans); // identity transformation
trans.SetMirror(mirrorAxis);
transformations.push_back(trans); // mirrored transformation
return transformations;
}
}

View File

@@ -0,0 +1,67 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTDESIGN_FeatureMirrored_H
#define PARTDESIGN_FeatureMirrored_H
#include <App/PropertyStandard.h>
#include "FeatureTransformed.h"
namespace PartDesign
{
class PartDesignExport Mirrored : public PartDesign::Transformed
{
PROPERTY_HEADER(PartDesign::Mirrored);
public:
Mirrored();
App::PropertyLinkSub MirrorPlane;
App::PropertyString StdMirrorPlane;
/** @name methods override feature */
//@{
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "PartDesignGui::ViewProviderMirrored";
}
//@}
/** Create transformations
* Returns a list containing one transformation since the first, untransformed instance
* is not counted. The transformation will mirror the shape it is applied to on a plane
* If StdMirrorPlane is "XY", "YZ" or "YZ" then the mirror plane will the corresponding plane
* If MirrorPlane contains a feature and an face name, then the mirror plane will be
* the the given face, which must be planar
*/
const std::list<gp_Trsf> getTransformations(const std::vector<App::DocumentObject*>);
};
} //namespace PartDesign
#endif // PARTDESIGN_FeatureMirrored_H

View File

@@ -0,0 +1,165 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Precision.hxx>
# include <GProp_GProps.hxx>
# include <BRepGProp.hxx>
#endif
#include "FeatureMultiTransform.h"
#include "FeatureScaled.h"
#include "FeatureAdditive.h"
#include "FeatureSubtractive.h"
#include <Mod/Part/App/TopoShape.h>
#include <Base/Console.h>
using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::MultiTransform, PartDesign::Transformed)
MultiTransform::MultiTransform()
{
ADD_PROPERTY(Transformations,(0));
Transformations.setSize(0);
}
short MultiTransform::mustExecute() const
{
if (Transformations.isTouched())
return 1;
return Transformed::mustExecute();
}
const std::list<gp_Trsf> MultiTransform::getTransformations(const std::vector<App::DocumentObject*> originals)
{
std::vector<App::DocumentObject*> transformationFeatures = Transformations.getValues();
// Find centre of gravity of first original
// FIXME: This method will NOT give the expected result for more than one original!
Part::Feature* originalFeature = static_cast<Part::Feature*>(originals.front());
TopoDS_Shape original;
if (originalFeature->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) {
PartDesign::Additive* addFeature = static_cast<PartDesign::Additive*>(originalFeature);
original = addFeature->AddShape.getShape()._Shape;
} else if (originalFeature->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(originalFeature);
original = subFeature->SubShape.getShape()._Shape;
}
GProp_GProps props;
BRepGProp::VolumeProperties(original,props);
gp_Pnt cog = props.CentreOfMass();
std::list<gp_Trsf> result;
std::list<gp_Pnt> cogs;
std::vector<App::DocumentObject*>::const_iterator f;
for (f = transformationFeatures.begin(); f != transformationFeatures.end(); f++) {
if (!((*f)->getTypeId().isDerivedFrom(PartDesign::Transformed::getClassTypeId())))
throw Base::Exception("Transformation features must be subclasses of Transformed");
PartDesign::Transformed* transFeature = static_cast<PartDesign::Transformed*>(*f);
std::list<gp_Trsf> newTransformations = transFeature->getTransformations(originals);
if (result.empty()) {
// First transformation Feature
result = newTransformations;
for (std::list<gp_Trsf>::const_iterator nt = newTransformations.begin(); nt != newTransformations.end(); nt++) {
cogs.push_back(cog.Transformed(*nt));
}
} else {
// Retain a copy of the first set of transformations for iterator ot
// We can't iterate through result if we are also adding elements with push_back()!
std::list<gp_Trsf> oldTransformations;
result.swap(oldTransformations); // empty result to receive new transformations
std::list<gp_Pnt> oldCogs;
cogs.swap(oldCogs); // empty cogs to receive new cogs
if ((*f)->getTypeId() == PartDesign::Scaled::getClassTypeId()) {
// Diagonal method
// Multiply every element in the old transformations' slices with the corresponding
// element in the newTransformations. Example:
// a11 a12 a13 a14 b1 a11*b1 a12*b1 a13*b1 a14*b1
// a21 a22 a23 a24 diag b2 = a21*b2 a22*b2 a23*b2 a24*b1
// a31 a23 a33 a34 b3 a31*b3 a23*b3 a33*b3 a34*b1
// In other words, the length of the result vector is equal to the length of the
// oldTransformations vector
if (oldTransformations.size() % newTransformations.size() != 0)
throw Base::Exception("Number of occurrences must be a divisor of previous number of occurrences");
unsigned sliceLength = oldTransformations.size() / newTransformations.size();
std::list<gp_Trsf>::const_iterator ot = oldTransformations.begin();
std::list<gp_Pnt>::const_iterator oc = oldCogs.begin();
for (std::list<gp_Trsf>::const_iterator nt = newTransformations.begin(); nt != newTransformations.end(); nt++) {
for (unsigned s = 0; s < sliceLength; s++) {
gp_Trsf trans;
double factor = nt->ScaleFactor(); // extract scale factor
if (factor > Precision::Confusion()) {
trans.SetScale(*oc, factor); // recreate the scaled transformation to use the correct COG
trans = trans * (*ot);
cogs.push_back(*oc); // Scaling does not affect the COG
} else {
trans = (*nt) * (*ot);
cogs.push_back(oc->Transformed(*nt));
}
result.push_back(trans);
ot++;
oc++;
}
}
} else {
// Multiplication method: Combine the new transformations with the old ones.
// All old transformations are multiplied with all new ones, so that the length of the
// result vector is the length of the old and new transformations multiplied.
// a11 a12 b1 a11*b1 a12*b1 a11*b2 a12*b2 a11*b3 a12*b3
// a21 a22 mul b2 = a21*b1 a22*b1 a21*b2 a22*b2 a21*b3 a22*b3
// b3
for (std::list<gp_Trsf>::const_iterator nt = newTransformations.begin(); nt != newTransformations.end(); nt++) {
std::list<gp_Pnt>::const_iterator oc = oldCogs.begin();
for (std::list<gp_Trsf>::const_iterator ot = oldTransformations.begin(); ot != oldTransformations.end(); ot++) {
result.push_back((*nt) * (*ot));
cogs.push_back(oc->Transformed(*nt));
oc++;
}
}
}
// What about the Additive method: Take the last (set of) transformations and use them as
// "originals" for the next transformationFeature, so that something similar to a sweep
// for transformations could be put together?
}
}
return result;
}
}

View File

@@ -1,62 +1,66 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 *
* *
***************************************************************************/
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTDESIGN_FeaturePatternRectangular_H
#define PARTDESIGN_FeaturePatternRectangular_H
#ifndef PARTDESIGN_FeatureMultiTransform_H
#define PARTDESIGN_FeatureMultiTransform_H
#include <App/PropertyStandard.h>
#include "Feature.h"
#include "FeatureTransformed.h"
namespace PartDesign
{
class PatternRectangular : public PartDesign::Feature
class PartDesignExport MultiTransform : public PartDesign::Transformed
{
PROPERTY_HEADER(PartDesign::SketchBased);
PROPERTY_HEADER(PartDesign::MultiTransform);
public:
PatternRectangular();
App::PropertyLink Base;
MultiTransform();
App::PropertyLinkList Transformations;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
//short mustExecute() const;
/// returns the type name of the view provider
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "PartDesignGui::ViewProviderPatternRectangular";
return "PartDesignGui::ViewProviderMultiTransform";
}
//@}
protected:
std::vector<App::DocumentObject*> getOriginals() const { return Originals.getValues(); }
/** Create transformations
* Returns a list containing the product of all transformations of the subfeatures given
* by the Transformations property. Subfeatures can be Mirrored, LinearPattern, PolarPattern and
* Scaled.
*/
const std::list<gp_Trsf> getTransformations(const std::vector<App::DocumentObject*> originals);
};
} //namespace PartDesign
#endif // PARTDESIGN_FeaturePatternRectangular_H
#endif // PARTDESIGN_FeatureMultiTransform_H

View File

@@ -1,153 +0,0 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Bnd_Box.hxx>
# include <BRep_Builder.hxx>
# include <BRepBndLib.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <BRepCheck_Analyzer.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Compound.hxx>
# include <TopoDS_Face.hxx>
# include <TopoDS_Wire.hxx>
# include <TopExp_Explorer.hxx>
# include <gp_Pln.hxx>
# include <ShapeFix_Face.hxx>
# include <ShapeFix_Wire.hxx>
# include <ShapeAnalysis.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
#endif
#include "FeaturePatternRectangular.h"
using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::PatternRectangular, PartDesign::Feature)
PatternRectangular::PatternRectangular()
{
ADD_PROPERTY(Base,(0));
}
//short PatternRectangular::mustExecute() const
//{
// if (Sketch.isTouched() ||
// Length.isTouched())
// return 1;
// return 0;
//}
App::DocumentObjectExecReturn *PatternRectangular::execute(void)
{
//App::DocumentObject* link = Sketch.getValue();
//if (!link)
// return new App::DocumentObjectExecReturn("No sketch linked");
//if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId()))
// return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject");
//TopoDS_Shape shape = static_cast<Part::Part2DObject*>(link)->Shape.getShape()._Shape;
//if (shape.IsNull())
// return new App::DocumentObjectExecReturn("Linked shape object is empty");
//// this is a workaround for an obscure OCC bug which leads to empty tessellations
//// for some faces. Making an explicit copy of the linked shape seems to fix it.
//// The error almost happens when re-computing the shape but sometimes also for the
//// first time
//BRepBuilderAPI_Copy copy(shape);
//shape = copy.Shape();
//if (shape.IsNull())
// return new App::DocumentObjectExecReturn("Linked shape object is empty");
//TopExp_Explorer ex;
//std::vector<TopoDS_Wire> wires;
//for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) {
// wires.push_back(TopoDS::Wire(ex.Current()));
//}
//if (/*shape.ShapeType() != TopAbs_WIRE*/wires.empty()) // there can be several wires
// return new App::DocumentObjectExecReturn("Linked shape object is not a wire");
//// get the Sketch plane
//Base::Placement SketchPos = static_cast<Part::Part2DObject*>(link)->Placement.getValue();
//Base::Rotation SketchOrientation = SketchPos.getRotation();
//Base::Vector3d SketchVector(0,0,1);
//SketchOrientation.multVec(SketchVector,SketchVector);
//// get the support of the Sketch if any
//App::DocumentObject* SupportLink = static_cast<Part::Part2DObject*>(link)->Support.getValue();
//Part::Feature *SupportObject = 0;
//if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
// SupportObject = static_cast<Part::Feature*>(SupportLink);
//if (!SupportObject)
// return new App::DocumentObjectExecReturn("No support in Sketch!");
//TopoDS_Shape aFace = makeFace(wires);
//if (aFace.IsNull())
// return new App::DocumentObjectExecReturn("Creating a face from sketch failed");
//// lengthen the vector
//SketchVector *= Length.getValue();
//// turn around for pockets
//SketchVector *= -1;
//// extrude the face to a solid
//gp_Vec vec(SketchVector.x,SketchVector.y,SketchVector.z);
//BRepPrimAPI_MakePrism PrismMaker(aFace,vec,0,1);
//if (PrismMaker.IsDone()) {
// // if the sketch has a support fuse them to get one result object (PAD!)
// if (SupportObject) {
// const TopoDS_Shape& support = SupportObject->Shape.getValue();
// if (support.IsNull())
// return new App::DocumentObjectExecReturn("Support shape is invalid");
// TopExp_Explorer xp (support, TopAbs_SOLID);
// if (!xp.More())
// return new App::DocumentObjectExecReturn("Support shape is not a solid");
// // Let's call algorithm computing a fuse operation:
// BRepAlgoAPI_Cut mkCut(support, PrismMaker.Shape());
// // Let's check if the fusion has been successful
// if (!mkCut.IsDone())
// return new App::DocumentObjectExecReturn("Cut with support failed");
// this->Shape.setValue(mkCut.Shape());
// }
// else{
// return new App::DocumentObjectExecReturn("Cannot create a tool out of sketch with no support");
// }
//}
//else
// return new App::DocumentObjectExecReturn("Could not extrude the sketch!");
return App::DocumentObject::StdReturn;
}
}

View File

@@ -0,0 +1,159 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <gp_Lin.hxx>
# include <gp_Ax2.hxx>
# include <BRepAdaptor_Curve.hxx>
#endif
#include "FeaturePolarPattern.h"
#include <Base/Tools.h>
#include <Base/Axis.h>
#include <Mod/Part/App/TopoShape.h>
using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::PolarPattern, PartDesign::Transformed)
PolarPattern::PolarPattern()
{
ADD_PROPERTY_TYPE(Axis,(0),"PolarPattern",(App::PropertyType)(App::Prop_None),"Direction");
ADD_PROPERTY(StdAxis,(""));
ADD_PROPERTY(Reversed,(0));
ADD_PROPERTY(Angle,(360.0));
ADD_PROPERTY(Occurrences,(3));
}
short PolarPattern::mustExecute() const
{
if (Axis.isTouched() ||
StdAxis.isTouched() ||
Reversed.isTouched() ||
Angle.isTouched() ||
Occurrences.isTouched())
return 1;
return Transformed::mustExecute();
}
const std::list<gp_Trsf> PolarPattern::getTransformations(const std::vector<App::DocumentObject*>)
{
std::string stdAxis = StdAxis.getValue();
float angle = Angle.getValue();
if (angle < Precision::Confusion())
throw Base::Exception("Pattern angle too small");
int occurrences = Occurrences.getValue();
if (occurrences < 2)
throw Base::Exception("At least two occurrences required");
bool reversed = Reversed.getValue();
double offset;
if (std::abs(angle - 360.0) < Precision::Confusion())
offset = Base::toRadians<double>(angle) / occurrences; // Because e.g. two occurrences in 360 degrees need to be 180 degrees apart
else
offset = Base::toRadians<double>(angle) / (occurrences - 1);
gp_Pnt axbase;
gp_Dir axdir;
if (!stdAxis.empty()) {
axbase = gp_Pnt(0,0,0);
if (stdAxis == "X") {
axdir = gp_Dir(1,0,0);
//ax = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0));
} else if (stdAxis == "Y") {
axdir = gp_Dir(0,1,0);
//ax = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0));
} else if(stdAxis == "Z") {
axdir = gp_Dir(0,0,1);
//ax = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,0,1));
} else {
throw Base::Exception("Invalid axis (must be X, Y or Z)");
}
} else {
App::DocumentObject* refObject = Axis.getValue();
if (refObject == NULL)
throw Base::Exception("No axis specified");
if (!refObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
throw Base::Exception("Axis reference must be edge of a feature");
std::vector<std::string> subStrings = Axis.getSubValues();
if (subStrings.empty() || subStrings[0].empty())
throw Base::Exception("No axis reference specified");
Part::Feature* refFeature = static_cast<Part::Feature*>(refObject);
Part::TopoShape refShape = refFeature->Shape.getShape();
TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str());
if (ref.ShapeType() == TopAbs_EDGE) {
TopoDS_Edge refEdge = TopoDS::Edge(ref);
if (refEdge.IsNull())
throw Base::Exception("Failed to extract axis edge");
BRepAdaptor_Curve adapt(refEdge);
if (adapt.GetType() != GeomAbs_Line)
throw Base::Exception("Axis edge must be a straight line");
axbase = adapt.Value(adapt.FirstParameter());
axdir = adapt.Line().Direction();
} else {
throw Base::Exception("Axis reference must be an edge");
}
TopLoc_Location invObjLoc = this->getLocation().Inverted();
axbase.Transform(invObjLoc.Transformation());
axdir.Transform(invObjLoc.Transformation());
}
// get the support placement
// TODO: Check for NULL pointer
/*Part::Feature* supportFeature = static_cast<Part::Feature*>(originals.front());
if (supportFeature == NULL)
throw Base::Exception("Cannot work on invalid support shape");
Base::Placement supportPlacement = supportFeature->Placement.getValue();
ax *= supportPlacement;
gp_Ax2 axis(gp_Pnt(ax.getBase().x, ax.getBase().y, ax.getBase().z), gp_Dir(ax.getDirection().x, ax.getDirection().y, ax.getDirection().z));*/
gp_Ax2 axis(axbase, axdir);
if (reversed)
axis.SetDirection(axis.Direction().Reversed());
// Note: The original feature is NOT included in the list of transformations! Therefore
// we start with occurrence number 1, not number 0
std::list<gp_Trsf> transformations;
gp_Trsf trans;
transformations.push_back(trans); // identity transformation
for (int i = 1; i < occurrences; i++) {
trans.SetRotation(axis.Axis(), i * offset);
transformations.push_back(trans);
}
return transformations;
}
}

View File

@@ -0,0 +1,74 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTDESIGN_FeaturePolarPattern_H
#define PARTDESIGN_FeaturePolarPattern_H
#include <App/PropertyStandard.h>
#include "FeatureTransformed.h"
namespace PartDesign
{
class PartDesignExport PolarPattern : public PartDesign::Transformed
{
PROPERTY_HEADER(PartDesign::PolarPattern);
public:
PolarPattern();
App::PropertyLinkSub Axis;
App::PropertyString StdAxis;
App::PropertyBool Reversed;
App::PropertyFloat Angle;
App::PropertyInteger Occurrences;
/** @name methods override feature */
//@{
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "PartDesignGui::ViewProviderPolarPattern";
}
//@}
/** Create transformations
* Returns a list of (Occurrences - 1) transformations since the first, untransformed instance
* is not counted. Each transformation will rotate the shape it is applied to by the angle
* (Angle / (Occurrences - 1)) so that the transformations will cover the total Angle. The only
* exception is Angle = 360 degrees in which case the transformation angle will be
* (Angle / Occurrences) so that the last transformed shape is not identical with the original shape
* If StdAxis is "X", "Y" or "Z" then the transformation axis will the corresponding axis
* If Axis contains a feature and an edge name, then the transformation axis will be
* the the given edge, which must be linear
* If Reversed is true, the direction of rotation will be opposite
*/
const std::list<gp_Trsf> getTransformations(const std::vector<App::DocumentObject*>);
};
} //namespace PartDesign
#endif // PARTDESIGN_FeaturePolarPattern_H

View File

@@ -0,0 +1,101 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Precision.hxx>
# include <GProp_GProps.hxx>
# include <BRepGProp.hxx>
#endif
#include "FeatureScaled.h"
#include "FeatureAdditive.h"
#include "FeatureSubtractive.h"
#include <Mod/Part/App/TopoShape.h>
using namespace PartDesign;
#include <Base/Console.h>
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::Scaled, PartDesign::Transformed)
Scaled::Scaled()
{
ADD_PROPERTY(Factor,(2.0));
ADD_PROPERTY(Occurrences,(2));
}
short Scaled::mustExecute() const
{
if (Factor.isTouched() ||
Occurrences.isTouched())
return 1;
return Transformed::mustExecute();
}
const std::list<gp_Trsf> Scaled::getTransformations(const std::vector<App::DocumentObject*> originals)
{
double factor = Factor.getValue();
if (factor < Precision::Confusion())
throw Base::Exception("Scaling factor too small");
int occurrences = Occurrences.getValue();
if (occurrences < 2)
throw Base::Exception("At least two occurrences required");
double f = (factor - 1.0) / double(occurrences - 1);
// Find centre of gravity of first original
// FIXME: This method will NOT give the expected result for more than one original!
Part::Feature* originalFeature = static_cast<Part::Feature*>(originals.front());
TopoDS_Shape original;
if (originalFeature->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) {
PartDesign::Additive* addFeature = static_cast<PartDesign::Additive*>(originalFeature);
original = addFeature->AddShape.getShape()._Shape;
} else if (originalFeature->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(originalFeature);
original = subFeature->SubShape.getShape()._Shape;
}
GProp_GProps props;
BRepGProp::VolumeProperties(original,props);
gp_Pnt cog = props.CentreOfMass();
// Note: The original feature is NOT included in the list of transformations! Therefore
// we start with occurrence number 1, not number 0
std::list<gp_Trsf> transformations;
gp_Trsf trans;
transformations.push_back(trans); // identity transformation
for (int i = 1; i < occurrences; i++) {
trans.SetScale(cog, 1.0 + double(i) * f);
transformations.push_back(trans);
}
return transformations;
}
}

View File

@@ -0,0 +1,69 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTDESIGN_FeatureScaled_H
#define PARTDESIGN_FeatureScaled_H
#include <App/PropertyStandard.h>
#include "FeatureTransformed.h"
namespace PartDesign
{
class PartDesignExport Scaled : public PartDesign::Transformed
{
PROPERTY_HEADER(PartDesign::Scaled);
public:
Scaled();
App::PropertyFloat Factor;
App::PropertyInteger Occurrences;
/** @name methods override feature */
//@{
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "PartDesignGui::ViewProviderScaled";
}
//@}
/** Create transformations
* Returns a list containing (Occurrences-1) transformation since the first, untransformed instance
* is not counted. Each transformation will scale the shape it is applied to by the factor
* (Factor / (Occurrences - 1))
* The centre point of the scaling (currently) is the centre of gravity of the first original shape
* for this reason we need to pass the list of originals into the feature
*/
// Note: We can't just use the Originals property because this will fail if the Scaled feature
// is being used inside a MultiTransform feature
const std::list<gp_Trsf> getTransformations(const std::vector<App::DocumentObject*> originals);
};
} //namespace PartDesign
#endif // PARTDESIGN_FeatureScaled_H

View File

@@ -0,0 +1,251 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepBuilderAPI_Transform.hxx>
# include <BRepAlgoAPI_Fuse.hxx>
# include <BRepAlgoAPI_Cut.hxx>
# include <BRep_Builder.hxx>
# include <TopExp.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
# include <Bnd_Box.hxx>
# include <BRepBndLib.hxx>
# include <Precision.hxx>
# include <BRepBuilderAPI_Copy.hxx>
#endif
#include "FeatureTransformed.h"
#include "FeatureMultiTransform.h"
#include "FeatureAdditive.h"
#include "FeatureSubtractive.h"
#include "FeatureMirrored.h"
#include <Base/Console.h>
using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::Transformed, PartDesign::Feature)
Transformed::Transformed()
{
ADD_PROPERTY(Originals,(0));
Originals.setSize(0);
}
void Transformed::positionBySupport(void)
{
Part::Feature *support = static_cast<Part::Feature*>(getOriginalObject());
if ((support != NULL) && support->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
this->Placement.setValue(support->Placement.getValue());
}
App::DocumentObject* Transformed::getOriginalObject() const
{
if (!Originals.getValues().empty())
return Originals.getValues().front();
else
return NULL;
}
short Transformed::mustExecute() const
{
if (Originals.isTouched())
return 1;
return PartDesign::Feature::mustExecute();
}
App::DocumentObjectExecReturn *Transformed::execute(void)
{
std::vector<App::DocumentObject*> originals = Originals.getValues();
if (originals.empty()) // typically InsideMultiTransform
return App::DocumentObject::StdReturn;
this->positionBySupport();
// get transformations from subclass by calling virtual method
std::list<gp_Trsf> transformations;
try {
transformations = getTransformations(originals);
} catch (Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what());
}
if (transformations.empty())
return App::DocumentObject::StdReturn; // No transformations defined, exit silently
// Get the support
// NOTE: Because of the way we define the support, FeatureTransformed can only work on
// one Body feature at a time
// TODO: Currently, the support is simply the first Original. Change this to the Body feature later
Part::Feature* supportFeature = static_cast<Part::Feature*>(originals.front());
const Part::TopoShape& supportTopShape = supportFeature->Shape.getShape();
if (supportTopShape._Shape.IsNull())
return new App::DocumentObjectExecReturn("Cannot transform invalid shape");
// create an untransformed copy of the support shape
Part::TopoShape supportShape(supportTopShape);
supportShape.setTransform(Base::Matrix4D());
TopoDS_Shape support = supportShape._Shape;
// Prepare a bounding box for intersection tests
Bnd_Box support_bb;
BRepBndLib::Add(support, support_bb);
// NOTE: It would be possible to build a compound from all original addShapes/subShapes and then
// transform the compounds as a whole. But we choose to apply the transformations to each
// Original separately. This way it is easier to discover what feature causes a fuse/cut
// to fail. The downside is that performance suffers when there are many originals. But it seems
// safe to assume that in most cases there are few originals and many transformations
for (std::vector<App::DocumentObject*>::const_iterator o = originals.begin(); o != originals.end(); o++)
{
TopoDS_Shape shape;
bool fuse;
if ((*o)->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) {
PartDesign::Additive* addFeature = static_cast<PartDesign::Additive*>(*o);
shape = addFeature->AddShape.getShape()._Shape;
fuse = true;
} else if ((*o)->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(*o);
shape = subFeature->SubShape.getShape()._Shape;
fuse = false;
} else {
return new App::DocumentObjectExecReturn("Only additive and subtractive features can be transformed");
}
// Transform the add/subshape and build a compound from the transformations,
BRep_Builder builder;
TopoDS_Compound transformedShapes;
builder.MakeCompound(transformedShapes);
std::vector<TopoDS_Shape> v_transformedShapes; // collect all the transformed shapes for history building
std::list<gp_Trsf>::const_iterator t = transformations.begin();
t++; // Skip first transformation, which is always the identity transformation
for (; t != transformations.end(); t++)
{
// Make an explicit copy of the shape because the "true" parameter to BRepBuilderAPI_Transform
// seems to be pretty broken
BRepBuilderAPI_Copy copy(shape);
shape = copy.Shape();
if (shape.IsNull())
throw Base::Exception("Transformed: Linked shape object is empty");
BRepBuilderAPI_Transform mkTrf(shape, *t, false); // No need to copy, now
if (!mkTrf.IsDone())
return new App::DocumentObjectExecReturn("Transformation failed", (*o));
// Check for intersection with support
Bnd_Box transformed_bb;
BRepBndLib::Add(mkTrf.Shape(), transformed_bb);
if (support_bb.Distance(transformed_bb) > Precision::Confusion()) {
Base::Console().Warning("Transformed shape does not intersect original %s: Removed\n", (*o)->getNameInDocument());
// Note: The removal happens in getSolid() after the fuse. If we remove here,
// the histories get messed up and we get a crash
}
builder.Add(transformedShapes, mkTrf.Shape());
v_transformedShapes.push_back(mkTrf.Shape());
/*
// Note: This method is only stable for Linear and Polar transformations. No need to
// make an explicit copy of the shape, either
TopoDS_Shape trfShape = shape.Moved(TopLoc_Location(*t));
// Check for intersection with support
Bnd_Box transformed_bb;
BRepBndLib::Add(trfShape, transformed_bb);
if (support_bb.Distance(transformed_bb) > Precision::Confusion()) {
Base::Console().Warning("Transformed shape does not intersect original %s: Removed\n", (*o)->getNameInDocument());
// Note: The removal happens in getSolid() after the fuse. If we remove here,
// the histories get messed up and we get a crash
}
builder.Add(transformedShapes, trfShape);
v_transformedShapes.push_back(trfShape);
*/
}
// Check for intersection of the original and the transformed shape
// Note: For performance reasons, we only check for intersection of bounding boxes
Bnd_Box original_bb;
BRepBndLib::Add(shape, original_bb);
original_bb.SetGap(0);
for (std::vector<TopoDS_Shape>::const_iterator s = v_transformedShapes.begin(); s != v_transformedShapes.end(); s++)
{
// If there is only one transformed feature, this check is not necessary (though it might seem
// illogical to the user why we allow overlapping shapes in this case!
if (v_transformedShapes.size() == 1)
break;
Bnd_Box transformed_bb;
BRepBndLib::Add(*s, transformed_bb);
transformed_bb.SetGap(0);
if (!original_bb.IsOut(transformed_bb))
// if (original_bb.Distance(transformed_bb) < Precision::Confusion())
// FIXME: Both tests fail if the objects are touching one another at zero distance
return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o));
// Note: This limitation could be overcome by fusing the transformed features instead of
// compounding them, probably at the expense of quite a bit of performance and complexity
// in this code
// For MultiTransform, just checking the first transformed shape is not sufficient - any two
// features might overlap, even if the original and the first shape don't overlap!
if (this->getTypeId() != PartDesign::MultiTransform::getClassTypeId())
break;
}
// Fuse/Cut the compounded transformed shapes with the support
TopoDS_Shape result;
if (fuse) {
BRepAlgoAPI_Fuse mkFuse(support, transformedShapes);
if (!mkFuse.IsDone())
return new App::DocumentObjectExecReturn("Fusion with support failed", *o);
// we have to get the solids (fuse sometimes creates compounds)
// Note: Because getSolid() only returns the first solid in the explorer, all
// solids that are outside the support automatically disappear!
result = this->getSolid(mkFuse.Shape());
// lets check if the result is a solid
if (result.IsNull())
return new App::DocumentObjectExecReturn("Transformed: Resulting shape is not a solid", *o);
} else {
BRepAlgoAPI_Cut mkCut(support, transformedShapes);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Cut out of support failed", *o);
result = mkCut.Shape();
}
support = result; // Use result of this operation for fuse/cut of next original
}
this->Shape.setValue(support);
return App::DocumentObject::StdReturn;
}
}

View File

@@ -0,0 +1,85 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTDESIGN_FeatureTransformed_H
#define PARTDESIGN_FeatureTransformed_H
#include <gp_Trsf.hxx>
#include <App/PropertyStandard.h>
#include "Feature.h"
namespace PartDesign
{
/**
* Abstract superclass of all features that are created by transformation of another feature
* Transformations are translation, rotation and mirroring
*/
class PartDesignExport Transformed : public PartDesign::Feature
{
PROPERTY_HEADER(PartDesign::Transformed);
public:
Transformed();
/** The shapes to be transformed
if Originals is empty the instance is just a container for storing transformation data */
App::PropertyLinkList Originals;
/// Return first original, which serves as "Support" until Body feature becomes functional
App::DocumentObject* getOriginalObject() const;
/// Get the list of transformations describing the members of the pattern
// Note: Only the Scaled feature requires the originals
virtual const std::list<gp_Trsf> getTransformations(const std::vector<App::DocumentObject*> originals) {
return std::list<gp_Trsf>(); // Default method
}
/** @name methods override feature */
//@{
/** Recalculate the feature
* Gets the transformations from the virtual getTransformations() method of the sub class
* and applies them to every member of Originals. The total number of copies including
* the untransformed Originals will be sizeof(Originals) times sizeof(getTransformations())
* If Originals is empty, execute() returns immediately without doing anything as
* the actual processing will happen in the MultiTransform feature
*/
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
//@}
void positionBySupport(void);
protected:
void buildTransformHistory(BRepBuilderAPI_MakeShape& mkFuse,
const TopoDS_Shape& newShape,
const TopoDS_Shape& oldShape,
const int index);
};
} //namespace PartDesign
#endif // PARTDESIGN_FeatureTransformed_H

View File

@@ -38,6 +38,11 @@
#include "ViewProviderFillet.h"
#include "ViewProviderRevolution.h"
#include "ViewProviderGroove.h"
#include "ViewProviderMirrored.h"
#include "ViewProviderLinearPattern.h"
#include "ViewProviderPolarPattern.h"
//#include "ViewProviderScaled.h"
#include "ViewProviderMultiTransform.h"
//#include "resources/qrc_PartDesign.cpp"
@@ -79,14 +84,19 @@ void PartDesignGuiExport initPartDesignGui()
// instantiating the commands
CreatePartDesignCommands();
PartDesignGui::Workbench ::init();
PartDesignGui::ViewProvider ::init();
PartDesignGui::ViewProviderPocket ::init();
PartDesignGui::ViewProviderPad ::init();
PartDesignGui::ViewProviderRevolution::init();
PartDesignGui::ViewProviderGroove ::init();
PartDesignGui::ViewProviderChamfer ::init();
PartDesignGui::ViewProviderFillet ::init();
PartDesignGui::Workbench ::init();
PartDesignGui::ViewProvider ::init();
PartDesignGui::ViewProviderPocket ::init();
PartDesignGui::ViewProviderPad ::init();
PartDesignGui::ViewProviderRevolution ::init();
PartDesignGui::ViewProviderGroove ::init();
PartDesignGui::ViewProviderChamfer ::init();
PartDesignGui::ViewProviderFillet ::init();
PartDesignGui::ViewProviderMirrored ::init();
PartDesignGui::ViewProviderLinearPattern ::init();
PartDesignGui::ViewProviderPolarPattern ::init();
// PartDesignGui::ViewProviderScaled ::init();
PartDesignGui::ViewProviderMultiTransform::init();
// add resources and reloads the translators
loadPartDesignResource();

View File

@@ -26,13 +26,18 @@ set(PartDesignGui_LIBS
set(PartDesignGui_MOC_HDRS
TaskPadParameters.h
TaskPatternRectangularParameters.h
TaskPocketParameters.h
TaskChamferParameters.h
TaskFilletParameters.h
TaskHoleParameters.h
TaskRevolutionParameters.h
TaskGrooveParameters.h
TaskTransformedParameters.h
TaskMirroredParameters.h
TaskLinearPatternParameters.h
TaskPolarPatternParameters.h
TaskScaledParameters.h
TaskMultiTransformParameters.h
)
fc_wrap_cpp(PartDesignGui_MOC_SRCS ${PartDesignGui_MOC_HDRS})
SOURCE_GROUP("Moc" FILES ${PartDesignGui_MOC_SRCS})
@@ -41,13 +46,17 @@ qt4_add_resources(PartDesignGui_SRCS Resources/PartDesign.qrc)
set(PartDesignGui_UIC_SRCS
TaskPadParameters.ui
TaskPatternRectangularParameters.ui
TaskPocketParameters.ui
TaskChamferParameters.ui
TaskFilletParameters.ui
TaskHoleParameters.ui
TaskRevolutionParameters.ui
TaskGrooveParameters.ui
TaskMirroredParameters.ui
TaskLinearPatternParameters.ui
TaskPolarPatternParameters.ui
TaskScaledParameters.ui
TaskMultiTransformParameters.ui
)
qt4_wrap_ui(PartDesignGui_UIC_HDRS ${PartDesignGui_UIC_SRCS})
@@ -68,8 +77,18 @@ SET(PartDesignGuiViewProvider_SRCS
ViewProviderRevolution.h
ViewProviderGroove.cpp
ViewProviderGroove.h
ViewProviderPatternRectangular.cpp
ViewProviderPatternRectangular.h
ViewProviderTransformed.cpp
ViewProviderTransformed.h
ViewProviderMirrored.cpp
ViewProviderMirrored.h
ViewProviderLinearPattern.cpp
ViewProviderLinearPattern.h
ViewProviderPolarPattern.cpp
ViewProviderPolarPattern.h
ViewProviderScaled.cpp
ViewProviderScaled.h
ViewProviderMultiTransform.cpp
ViewProviderMultiTransform.h
)
SOURCE_GROUP("ViewProvider" FILES ${PartDesignGuiViewProvider_SRCS})
@@ -77,9 +96,6 @@ SET(PartDesignGuiTaskDlgs_SRCS
TaskPadParameters.ui
TaskPadParameters.cpp
TaskPadParameters.h
TaskPatternRectangularParameters.ui
TaskPatternRectangularParameters.cpp
TaskPatternRectangularParameters.h
TaskPocketParameters.ui
TaskPocketParameters.cpp
TaskPocketParameters.h
@@ -95,6 +111,23 @@ SET(PartDesignGuiTaskDlgs_SRCS
TaskGrooveParameters.ui
TaskGrooveParameters.cpp
TaskGrooveParameters.h
TaskTransformedParameters.h
TaskTransformedParameters.cpp
TaskMirroredParameters.ui
TaskMirroredParameters.cpp
TaskMirroredParameters.h
TaskLinearPatternParameters.ui
TaskLinearPatternParameters.cpp
TaskLinearPatternParameters.h
TaskPolarPatternParameters.ui
TaskPolarPatternParameters.cpp
TaskPolarPatternParameters.h
TaskScaledParameters.ui
TaskScaledParameters.cpp
TaskScaledParameters.h
TaskMultiTransformParameters.ui
TaskMultiTransformParameters.cpp
TaskMultiTransformParameters.h
TaskHoleParameters.ui
TaskHoleParameters.cpp
TaskHoleParameters.h

View File

@@ -47,7 +47,8 @@
#include <Gui/FileDialog.h>
#include <Mod/Part/App/Part2DObject.h>
#include <Mod/PartDesign/App/FeatureAdditive.h>
#include <Mod/PartDesign/App/FeatureSubtractive.h>
using namespace std;
@@ -697,6 +698,319 @@ bool CmdPartDesignChamfer::isActive(void)
return hasActiveDocument();
}
//===========================================================================
// PartDesign_Mirrored
//===========================================================================
DEF_STD_CMD_A(CmdPartDesignMirrored);
CmdPartDesignMirrored::CmdPartDesignMirrored()
: Command("PartDesign_Mirrored")
{
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("Mirrored");
sToolTipText = QT_TR_NOOP("create a mirrored feature");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "PartDesign_Mirrored";
}
void CmdPartDesignMirrored::activated(int iMsg)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
if (n < 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select one or more additive/subtractive features, please."));
return;
}
std::string FeatName = getUniqueObjectName("Mirrored");
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::stringstream str;
std::vector<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Originals = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
}
str << "]";
openCommand("Mirrored");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",FeatName.c_str());
// FIXME: There seems to be kind of a race condition here, leading to sporadic errors like
// Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored'
updateActive(); // Helps to ensure that the object already exists when the next command comes up
doCommand(Doc,str.str().c_str());
doCommand(Doc,"App.activeDocument().%s.StdMirrorPlane = \"XY\"", FeatName.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());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str());
copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str());
}
bool CmdPartDesignMirrored::isActive(void)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
return n >= 1;
}
//===========================================================================
// PartDesign_LinearPattern
//===========================================================================
DEF_STD_CMD_A(CmdPartDesignLinearPattern);
CmdPartDesignLinearPattern::CmdPartDesignLinearPattern()
: Command("PartDesign_LinearPattern")
{
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("LinearPattern");
sToolTipText = QT_TR_NOOP("create a linear pattern feature");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "PartDesign_LinearPattern";
}
void CmdPartDesignLinearPattern::activated(int iMsg)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
if (n < 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select one or more additive/subtractive features, please."));
return;
}
std::string FeatName = getUniqueObjectName("LinearPattern");
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::stringstream str;
std::vector<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Originals = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
}
str << "]";
openCommand("LinearPattern");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Doc,str.str().c_str());
doCommand(Doc,"App.activeDocument().%s.StdDirection = \"X\"", FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.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());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str());
copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str());
}
bool CmdPartDesignLinearPattern::isActive(void)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
return n >= 1;
}
//===========================================================================
// PartDesign_PolarPattern
//===========================================================================
DEF_STD_CMD_A(CmdPartDesignPolarPattern);
CmdPartDesignPolarPattern::CmdPartDesignPolarPattern()
: Command("PartDesign_PolarPattern")
{
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("PolarPattern");
sToolTipText = QT_TR_NOOP("create a polar pattern feature");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "PartDesign_PolarPattern";
}
void CmdPartDesignPolarPattern::activated(int iMsg)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
if (n < 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select one or more additive/subtractive features, please."));
return;
}
std::string FeatName = getUniqueObjectName("PolarPattern");
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::stringstream str;
std::vector<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Originals = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
}
str << "]";
openCommand("PolarPattern");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Doc,str.str().c_str());
doCommand(Doc,"App.activeDocument().%s.StdAxis = \"X\"", FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.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());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str());
copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str());
}
bool CmdPartDesignPolarPattern::isActive(void)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
return n >= 1;
}
//===========================================================================
// PartDesign_Scaled
//===========================================================================
DEF_STD_CMD_A(CmdPartDesignScaled);
CmdPartDesignScaled::CmdPartDesignScaled()
: Command("PartDesign_Scaled")
{
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("Scaled");
sToolTipText = QT_TR_NOOP("create a scaled feature");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "PartDesign_Scaled";
}
void CmdPartDesignScaled::activated(int iMsg)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
if (n < 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select one or more additive/subtractive features, please."));
return;
}
std::string FeatName = getUniqueObjectName("Scaled");
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::stringstream str;
std::vector<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Originals = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
}
str << "]";
openCommand("Scaled");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Doc,str.str().c_str());
doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.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());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str());
copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str());
}
bool CmdPartDesignScaled::isActive(void)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
return n >= 1;
}
//===========================================================================
// PartDesign_MultiTransform
//===========================================================================
DEF_STD_CMD_A(CmdPartDesignMultiTransform);
CmdPartDesignMultiTransform::CmdPartDesignMultiTransform()
: Command("PartDesign_MultiTransform")
{
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("MultiTransform");
sToolTipText = QT_TR_NOOP("create a multitransform feature");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "PartDesign_MultiTransform";
}
void CmdPartDesignMultiTransform::activated(int iMsg)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
if (n < 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select one or more additive/subtractive features, please."));
return;
}
std::string FeatName = getUniqueObjectName("MultiTransform");
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::stringstream str;
std::vector<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Originals = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
}
str << "]";
openCommand("MultiTransform");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::MultiTransform\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Doc,str.str().c_str());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str());
copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str());
}
bool CmdPartDesignMultiTransform::isActive(void)
{
unsigned n = getSelection().countObjectsOfType(PartDesign::Additive::getClassTypeId()) +
getSelection().countObjectsOfType(PartDesign::Subtractive::getClassTypeId());
return n >= 1;
}
//===========================================================================
// Initialization
//===========================================================================
void CreatePartDesignCommands(void)
{
@@ -709,4 +1023,9 @@ void CreatePartDesignCommands(void)
rcCmdMgr.addCommand(new CmdPartDesignFillet());
//rcCmdMgr.addCommand(new CmdPartDesignNewSketch());
rcCmdMgr.addCommand(new CmdPartDesignChamfer());
rcCmdMgr.addCommand(new CmdPartDesignMirrored());
rcCmdMgr.addCommand(new CmdPartDesignLinearPattern());
rcCmdMgr.addCommand(new CmdPartDesignPolarPattern());
//rcCmdMgr.addCommand(new CmdPartDesignScaled());
rcCmdMgr.addCommand(new CmdPartDesignMultiTransform());
}

View File

@@ -43,6 +43,11 @@ EXTRA_DIST = \
icons/PartDesign_Pad.svg \
icons/PartDesign_Pocket.svg \
icons/PartDesign_Revolution.svg \
icons/PartDesign_Mirrored.svg \
icons/PartDesign_LinearPattern.svg \
icons/PartDesign_PolarPattern.svg \
icons/PartDesign_Scaled.svg \
icons/PartDesign_MultiTransform.svg \
PartDesign.qrc

View File

@@ -6,6 +6,11 @@
<file>icons/PartDesign_Pad.svg</file>
<file>icons/PartDesign_Pocket.svg</file>
<file>icons/PartDesign_Revolution.svg</file>
<file>icons/PartDesign_Mirrored.svg</file>
<file>icons/PartDesign_LinearPattern.svg</file>
<file>icons/PartDesign_PolarPattern.svg</file>
<file>icons/PartDesign_Scaled.svg</file>
<file>icons/PartDesign_MultiTransform.svg</file>
<file>translations/PartDesign_af.qm</file>
<file>translations/PartDesign_de.qm</file>
<file>translations/PartDesign_es.qm</file>

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -0,0 +1,429 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg3364"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="PartDesign_Mirrored.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs3366">
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3864"
id="radialGradient2571"
gradientUnits="userSpaceOnUse"
cx="342.58258"
cy="27.256668"
fx="342.58258"
fy="27.256668"
r="19.571428"
gradientTransform="matrix(1.6258409,0.5434973,-8.8819886e-2,0.2656996,-215.02413,-170.90186)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593"
id="radialGradient3352"
gradientUnits="userSpaceOnUse"
cx="345.28433"
cy="15.560534"
fx="345.28433"
fy="15.560534"
r="19.571428"
gradientTransform="translate(-0.1767767,-2.6516504)" />
<linearGradient
id="linearGradient3593">
<stop
style="stop-color:#c8e0f9;stop-opacity:1;"
offset="0"
id="stop3595" />
<stop
style="stop-color:#637dca;stop-opacity:1;"
offset="1"
id="stop3597" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593"
id="radialGradient3354"
gradientUnits="userSpaceOnUse"
cx="330.63791"
cy="39.962704"
fx="330.63791"
fy="39.962704"
r="19.571428"
gradientTransform="translate(-0.1767767,-2.6516504)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective3372" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3864"
id="radialGradient3369"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6258409,0.5434973,-8.8819886e-2,0.2656996,-461.81066,-173.06271)"
cx="342.58258"
cy="27.256668"
fx="342.58258"
fy="27.256668"
r="19.571428" />
<inkscape:perspective
id="perspective4589"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3027"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
id="linearGradient3864-4">
<stop
id="stop3866-5"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868-2"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
r="19.571428"
fy="113.23357"
fx="320.44025"
cy="113.23357"
cx="320.44025"
gradientTransform="matrix(0.9829174,1.3240854,-1.2330051,0.8105158,-138.75617,-494.52855)"
gradientUnits="userSpaceOnUse"
id="radialGradient3036"
xlink:href="#linearGradient3864-4"
inkscape:collect="always" />
<inkscape:perspective
id="perspective3840"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3864-6"
id="radialGradient3007-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9829174,1.3240854,-1.2330051,0.8105158,-189.40979,-484.51702)"
cx="320.44025"
cy="113.23357"
fx="320.44025"
fy="113.23357"
r="19.571428" />
<linearGradient
id="linearGradient3864-6">
<stop
id="stop3866-0"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868-9"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
id="perspective3977"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3864-1"
id="radialGradient3960"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.2993671,-0.01575726,0.0084161,0.9850979,-94.354208,-10.998387)"
cx="48.288067"
cy="46.74614"
fx="48.288067"
fy="46.74614"
r="19.571428" />
<linearGradient
id="linearGradient3864-1">
<stop
id="stop3866-9"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868-0"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
id="perspective4015"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
r="19.571428"
fy="32.799232"
fx="41.803806"
cy="32.799232"
cx="41.803806"
gradientTransform="matrix(-0.70352355,2.1948421,-1.0402627,-0.30894741,102.4266,-56.052881)"
gradientUnits="userSpaceOnUse"
id="radialGradient3986-4"
xlink:href="#linearGradient3864-1-9"
inkscape:collect="always" />
<linearGradient
id="linearGradient3864-1-9">
<stop
id="stop3866-9-6"
offset="0"
style="stop-color:#ffa200;stop-opacity:1;" />
<stop
id="stop3868-0-6"
offset="1"
style="stop-color:#ffe83f;stop-opacity:1;" />
</linearGradient>
<radialGradient
r="19.571428"
fy="46.74614"
fx="48.288067"
cy="46.74614"
cx="48.288067"
gradientTransform="matrix(0.01575726,2.2993671,-0.9850979,0.0084161,52.182614,-97.493771)"
gradientUnits="userSpaceOnUse"
id="radialGradient4024"
xlink:href="#linearGradient3864-1-9"
inkscape:collect="always" />
<inkscape:perspective
id="perspective4052"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593-5"
id="radialGradient3966"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9327663,0,0,0.9327663,-298.15651,8.1913381)"
cx="330.63791"
cy="39.962704"
fx="330.63791"
fy="39.962704"
r="19.571428" />
<linearGradient
id="linearGradient3593-5">
<stop
style="stop-color:#c8e0f9;stop-opacity:1;"
offset="0"
id="stop3595-2" />
<stop
style="stop-color:#637dca;stop-opacity:1;"
offset="1"
id="stop3597-5" />
</linearGradient>
<inkscape:perspective
id="perspective4090"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
r="19.571428"
fy="6.0560789"
fx="374.42535"
cy="6.0560789"
cx="374.42535"
gradientTransform="matrix(0.52013132,0.80077671,-0.81763607,0.49523365,-185.59014,-277.02153)"
gradientUnits="userSpaceOnUse"
id="radialGradient4061-4"
xlink:href="#linearGradient3864-1-9"
inkscape:collect="always" />
<linearGradient
id="linearGradient3593-5-4">
<stop
style="stop-color:#c8e0f9;stop-opacity:1;"
offset="0"
id="stop3595-2-8" />
<stop
style="stop-color:#637dca;stop-opacity:1;"
offset="1"
id="stop3597-5-4" />
</linearGradient>
<radialGradient
r="19.571428"
fy="39.962704"
fx="330.63791"
cy="39.962704"
cx="330.63791"
gradientTransform="matrix(0.9327663,0,0,0.9327663,-302.00666,-27.942952)"
gradientUnits="userSpaceOnUse"
id="radialGradient4099"
xlink:href="#linearGradient3593-5-4"
inkscape:collect="always" />
<inkscape:perspective
id="perspective4127"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
id="linearGradient3864-1-9-2">
<stop
id="stop3866-9-6-6"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868-0-6-8"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
r="19.571428"
fy="6.0560789"
fx="374.42535"
cy="6.0560789"
cx="374.42535"
gradientTransform="matrix(0.52013132,0.80077671,-0.81763607,0.49523365,-185.59014,-276.99255)"
gradientUnits="userSpaceOnUse"
id="radialGradient4061-4-8"
xlink:href="#linearGradient3593-5-4-9"
inkscape:collect="always" />
<linearGradient
id="linearGradient3593-5-4-9">
<stop
style="stop-color:#c8e0f9;stop-opacity:1;"
offset="0"
id="stop3595-2-8-8" />
<stop
style="stop-color:#637dca;stop-opacity:1;"
offset="1"
id="stop3597-5-4-8" />
</linearGradient>
<inkscape:perspective
id="perspective3660"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3682"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="-15.605041"
inkscape:cy="27.671071"
inkscape:current-layer="g3922"
showgrid="false"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1400"
inkscape:window-height="963"
inkscape:window-x="0"
inkscape:window-y="28"
showguides="false"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid5773" />
</sodipodi:namedview>
<metadata
id="metadata3369">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3922">
<path
sodipodi:nodetypes="cczccc"
id="rect2568"
d="M 23.429771,42.610701 5.3467503,53.030534 c 0,0 0,-11.350414 0,-16.752894 0,-5.40248 0,-15.661985 0,-15.661985 l 18.0830207,-10.419833 0,32.414879 z"
style="color:#000000;fill:url(#radialGradient4061-4);fill-opacity:1.0;fill-rule:evenodd;stroke:#4b4dba;stroke-width:2.23698138999999996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cczccc"
id="rect2568-8"
d="M 40.035019,42.610701 58.11804,53.030534 c 0,0 0,-10.623141 0,-16.025621 0,-5.40248 0,-16.389258 0,-16.389258 l -18.083021,-10.419833 0,32.414879 z"
style="color:#000000;fill:url(#radialGradient3986-4);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.23698138999999996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="opacity:1;color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:15, 5;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2878"
width="5.272727"
height="15.454545"
x="29.272728"
y="3.4545457" />
<rect
style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2878-2"
width="5.272727"
height="15.454545"
x="29.272728"
y="23.454546" />
<rect
style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2878-2-4"
width="5.272727"
height="15.454545"
x="29.272728"
y="43.454544" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 63 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,430 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMessageBox>
#endif
#include "ui_TaskLinearPatternParameters.h"
#include "TaskLinearPatternParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeatureLinearPattern.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "TaskMultiTransformParameters.h"
using namespace PartDesignGui;
using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskLinearPatternParameters */
TaskLinearPatternParameters::TaskLinearPatternParameters(ViewProviderTransformed *TransformedView,QWidget *parent)
: TaskTransformedParameters(TransformedView, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskLinearPatternParameters();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
ui->buttonOK->hide();
ui->checkBoxUpdateView->setEnabled(true);
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
TaskLinearPatternParameters::TaskLinearPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout)
: TaskTransformedParameters(parentTask)
{
proxy = new QWidget(parentTask);
ui = new Ui_TaskLinearPatternParameters();
ui->setupUi(proxy);
connect(ui->buttonOK, SIGNAL(pressed()),
parentTask, SLOT(onSubTaskButtonOK()));
QMetaObject::connectSlotsByName(this);
layout->addWidget(proxy);
ui->buttonOK->setEnabled(true);
ui->listFeatures->hide();
ui->checkBoxUpdateView->hide();
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
void TaskLinearPatternParameters::setupUI()
{
connect(ui->buttonX, SIGNAL(pressed()),
this, SLOT(onButtonX()));
connect(ui->buttonY, SIGNAL(pressed()),
this, SLOT(onButtonY()));
connect(ui->buttonZ, SIGNAL(pressed()),
this, SLOT(onButtonZ()));
connect(ui->checkReverse, SIGNAL(toggled(bool)),
this, SLOT(onCheckReverse(bool)));
connect(ui->spinLength, SIGNAL(valueChanged(double)),
this, SLOT(onLength(double)));
connect(ui->spinOccurrences, SIGNAL(valueChanged(int)),
this, SLOT(onOccurrences(int)));
connect(ui->buttonReference, SIGNAL(pressed()),
this, SLOT(onButtonReference()));
connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)),
this, SLOT(onUpdateView(bool)));
// TODO: The following code could be generic in TaskTransformedParameters
// if it were possible to make ui_TaskLinearPatternParameters a subclass of
// ui_TaskTransformedParameters
// ---------------------
// Add a context menu to the listview of the originals to delete items
QAction* action = new QAction(tr("Delete"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onOriginalDeleted()));
ui->listFeatures->addAction(action);
ui->listFeatures->setContextMenuPolicy(Qt::ActionsContextMenu);
// Get the feature data
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
std::vector<App::DocumentObject*> originals = pcLinearPattern->Originals.getValues();
// Fill data into dialog elements
ui->listFeatures->setEnabled(true);
ui->listFeatures->clear();
for (std::vector<App::DocumentObject*>::const_iterator i = originals.begin(); i != originals.end(); i++)
{
if ((*i) != NULL)
ui->listFeatures->addItem(QString::fromAscii((*i)->getNameInDocument()));
}
QMetaObject::invokeMethod(ui->listFeatures, "setFocus", Qt::QueuedConnection);
// ---------------------
ui->buttonX->setEnabled(true);
ui->buttonY->setEnabled(true);
ui->buttonZ->setEnabled(true);
ui->checkReverse->setEnabled(true);
ui->spinLength->setEnabled(true);
ui->spinOccurrences->setEnabled(true);
ui->buttonReference->setEnabled(true);
ui->lineReference->setEnabled(false); // This is never enabled since it is for optical feed-back only
updateUI();
}
void TaskLinearPatternParameters::updateUI()
{
if (updateUIinProgress) return;
updateUIinProgress = true;
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
App::DocumentObject* directionFeature = pcLinearPattern->Direction.getValue();
std::vector<std::string> directions = pcLinearPattern->Direction.getSubValues();
std::string stdDirection = pcLinearPattern->StdDirection.getValue();
bool reverse = pcLinearPattern->Reversed.getValue();
double length = pcLinearPattern->Length.getValue();
unsigned occurrences = pcLinearPattern->Occurrences.getValue();
if ((featureSelectionMode || insideMultiTransform) && !stdDirection.empty())
{
ui->buttonReference->setDown(false);
ui->buttonX->setAutoExclusive(true);
ui->buttonY->setAutoExclusive(true);
ui->buttonZ->setAutoExclusive(true);
ui->buttonX->setChecked(stdDirection == "X");
ui->buttonY->setChecked(stdDirection == "Y");
ui->buttonZ->setChecked(stdDirection == "Z");
ui->lineReference->setText(tr(""));
} else if ((directionFeature != NULL) && !directions.empty()) {
ui->buttonX->setAutoExclusive(false);
ui->buttonY->setAutoExclusive(false);
ui->buttonZ->setAutoExclusive(false);
ui->buttonX->setChecked(false);
ui->buttonY->setChecked(false);
ui->buttonZ->setChecked(false);
ui->buttonReference->setDown(!featureSelectionMode);
ui->lineReference->setText(QString::fromAscii(directions.front().c_str()));
} else {
// Error message?
ui->lineReference->setText(tr(""));
}
// Note: These three lines would trigger onLength(), on Occurrences() and another updateUI() if we
// didn't check for updateUIinProgress
ui->checkReverse->setChecked(reverse);
ui->spinLength->setValue(length);
ui->spinOccurrences->setValue(occurrences);
updateUIinProgress = false;
}
void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
App::DocumentObject* selectedObject = pcLinearPattern->getDocument()->getActiveObject();
if ((selectedObject == NULL) || !selectedObject->isDerivedFrom(Part::Feature::getClassTypeId()))
return;
if (featureSelectionMode) {
if (originalSelected(msg))
ui->listFeatures->addItem(QString::fromAscii(selectedObject->getNameInDocument()));
} else {
if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string element(msg.pSubName);
if (msg.Type == Gui::SelectionChanges::AddSelection) {
// TODO
// if (originalElementName == "") {
// Base::Console().Error("Element created by this pattern cannot be used for direction\n");
// return;
// }
std::vector<std::string> directions;
directions.push_back(element.c_str());
pcLinearPattern->Direction.setValue(getOriginalObject(), directions);
if (insideMultiTransform) {
if (parentTask->updateView())
recomputeFeature();
} else
if (ui->checkBoxUpdateView->isChecked())
recomputeFeature();
if (!insideMultiTransform)
featureSelectionMode = true; // Jump back to selection of originals
showObject();
hideOriginals();
updateUI();
}
}
}
void TaskLinearPatternParameters::onOriginalDeleted()
{
int row = ui->listFeatures->currentIndex().row();
TaskTransformedParameters::onOriginalDeleted(row);
ui->listFeatures->model()->removeRow(row);
}
void TaskLinearPatternParameters::onButtonX() {
onStdDirection("X");
}
void TaskLinearPatternParameters::onButtonY() {
onStdDirection("Y");
}
void TaskLinearPatternParameters::onButtonZ() {
onStdDirection("Z");
}
void TaskLinearPatternParameters::onCheckReverse(const bool on) {
if (updateUIinProgress) return;
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
pcLinearPattern->Reversed.setValue(on);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskLinearPatternParameters::onLength(const double l) {
if (updateUIinProgress) return;
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
pcLinearPattern->Length.setValue(l);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskLinearPatternParameters::onOccurrences(const int n) {
if (updateUIinProgress) return;
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
pcLinearPattern->Occurrences.setValue(n);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskLinearPatternParameters::onStdDirection(const std::string& dir) {
if (updateUIinProgress) return;
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
pcLinearPattern->StdDirection.setValue(dir.c_str());
pcLinearPattern->Direction.setValue(NULL);
if (!insideMultiTransform)
featureSelectionMode = true;
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskLinearPatternParameters::onButtonReference()
{
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
pcLinearPattern->StdDirection.setValue("");
featureSelectionMode = false;
hideObject();
showOriginals();
updateUI();
}
void TaskLinearPatternParameters::onUpdateView(bool on)
{
ui->buttonX->blockSignals(!on);
ui->buttonY->blockSignals(!on);
ui->buttonZ->blockSignals(!on);
ui->listFeatures->blockSignals(!on);
ui->checkReverse->blockSignals(!on);
ui->spinLength->blockSignals(!on);
ui->spinOccurrences->blockSignals(!on);
}
const std::string TaskLinearPatternParameters::getStdDirection(void) const
{
std::string stdDirection;
if (ui->buttonX->isChecked())
stdDirection = "X";
else if (ui->buttonY->isChecked())
stdDirection = "Y";
else if (ui->buttonZ->isChecked())
stdDirection = "Z";
if (!stdDirection.empty())
return std::string("\"") + stdDirection + "\"";
else
return std::string("");
}
const QString TaskLinearPatternParameters::getDirection(void) const
{
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(getObject());
App::DocumentObject* feature = pcLinearPattern->Direction.getValue();
if (feature == NULL)
return QString::fromUtf8("");
std::vector<std::string> directions = pcLinearPattern->Direction.getSubValues();
QString buf;
if ((feature != NULL) && !directions.empty()) {
buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])");
buf = buf.arg(QString::fromUtf8(feature->getNameInDocument()));
buf = buf.arg(QString::fromUtf8(directions.front().c_str()));
}
else
buf = QString::fromUtf8("");
return buf;
}
const bool TaskLinearPatternParameters::getReverse(void) const {
return ui->checkReverse->isChecked();
}
const double TaskLinearPatternParameters::getLength(void) const {
return ui->spinLength->value();
}
const unsigned TaskLinearPatternParameters::getOccurrences(void) const {
return ui->spinOccurrences->value();
}
TaskLinearPatternParameters::~TaskLinearPatternParameters()
{
delete ui;
if (proxy)
delete proxy;
}
void TaskLinearPatternParameters::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(proxy);
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgLinearPatternParameters::TaskDlgLinearPatternParameters(ViewProviderLinearPattern *LinearPatternView)
: TaskDlgTransformedParameters(LinearPatternView)
{
parameter = new TaskLinearPatternParameters(LinearPatternView);
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgLinearPatternParameters::accept()
{
std::string name = TransformedView->getObject()->getNameInDocument();
try {
//Gui::Command::openCommand("LinearPattern changed");
// Handle Originals
if (!TaskDlgTransformedParameters::accept())
return false;
TaskLinearPatternParameters* linearpatternParameter = static_cast<TaskLinearPatternParameters*>(parameter);
std::string direction = linearpatternParameter->getDirection().toStdString();
if (!direction.empty())
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), direction.c_str());
std::string stdDirection = linearpatternParameter->getStdDirection();
if (!stdDirection.empty())
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.StdDirection = %s",name.c_str(),stdDirection.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),linearpatternParameter->getReverse());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Length = %f",name.c_str(),linearpatternParameter->getLength());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Occurrences = %u",name.c_str(),linearpatternParameter->getOccurrences());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
if (!TransformedView->getObject()->isValid())
throw Base::Exception(TransformedView->getObject()->getStatusString());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return true;
}
#include "moc_TaskLinearPatternParameters.cpp"

View File

@@ -0,0 +1,106 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 GUI_TASKVIEW_TaskLinearPatternParameters_H
#define GUI_TASKVIEW_TaskLinearPatternParameters_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskTransformedParameters.h"
#include "ViewProviderLinearPattern.h"
class Ui_TaskLinearPatternParameters;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace PartDesignGui {
class TaskMultiTransformParameters;
class TaskLinearPatternParameters : public TaskTransformedParameters
{
Q_OBJECT
public:
/// Constructor for task with ViewProvider
TaskLinearPatternParameters(ViewProviderTransformed *TransformedView, QWidget *parent = 0);
/// Constructor for task with parent task (MultiTransform mode)
TaskLinearPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout);
virtual ~TaskLinearPatternParameters();
const QString getDirection(void) const;
const std::string getStdDirection(void) const;
const bool getReverse(void) const;
const double getLength(void) const;
const unsigned getOccurrences(void) const;
private Q_SLOTS:
void onStdDirection(const std::string& dir);
void onButtonX();
void onButtonY();
void onButtonZ();
void onCheckReverse(const bool on);
void onLength(const double l);
void onOccurrences(const int n);
virtual void onButtonReference();
virtual void onOriginalDeleted();
virtual void onUpdateView(bool);
protected:
virtual void changeEvent(QEvent *e);
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
private:
void updateUI();
void setupUI();
private:
Ui_TaskLinearPatternParameters* ui;
};
/// simulation dialog for the TaskView
class TaskDlgLinearPatternParameters : public TaskDlgTransformedParameters
{
Q_OBJECT
public:
TaskDlgLinearPatternParameters(ViewProviderLinearPattern *LinearPatternView);
virtual ~TaskDlgLinearPatternParameters() {}
public:
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartDesignGui::TaskLinearPatternParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskLinearPatternParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>402</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="buttonX">
<property name="text">
<string>X</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="buttonY">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="buttonZ">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QToolButton" name="buttonReference">
<property name="text">
<string>Direction</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineReference"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkReverse">
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Length</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinLength">
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Occurrences</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinOccurrences">
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QPushButton" name="buttonOK">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBoxUpdateView">
<property name="text">
<string>Update view</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,361 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMessageBox>
#endif
#include "ui_TaskMirroredParameters.h"
#include "TaskMirroredParameters.h"
#include "TaskMultiTransformParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeatureMirrored.h>
#include <Mod/Sketcher/App/SketchObject.h>
using namespace PartDesignGui;
using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskMirroredParameters */
TaskMirroredParameters::TaskMirroredParameters(ViewProviderTransformed *TransformedView, QWidget *parent)
: TaskTransformedParameters(TransformedView, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskMirroredParameters();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
ui->buttonOK->hide();
ui->checkBoxUpdateView->setEnabled(true);
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
TaskMirroredParameters::TaskMirroredParameters(TaskMultiTransformParameters *parentTask, QLayout *layout)
: TaskTransformedParameters(parentTask)
{
proxy = new QWidget(parentTask);
ui = new Ui_TaskMirroredParameters();
ui->setupUi(proxy);
connect(ui->buttonOK, SIGNAL(pressed()),
parentTask, SLOT(onSubTaskButtonOK()));
QMetaObject::connectSlotsByName(this);
layout->addWidget(proxy);
ui->buttonOK->setEnabled(true);
ui->listFeatures->hide();
ui->checkBoxUpdateView->hide();
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
void TaskMirroredParameters::setupUI()
{
connect(ui->buttonXY, SIGNAL(pressed()),
this, SLOT(onButtonXY()));
connect(ui->buttonXZ, SIGNAL(pressed()),
this, SLOT(onButtonXZ()));
connect(ui->buttonYZ, SIGNAL(pressed()),
this, SLOT(onButtonYZ()));
connect(ui->buttonReference, SIGNAL(pressed()),
this, SLOT(onButtonReference()));
connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)),
this, SLOT(onUpdateView(bool)));
// TODO: The following code could be generic in TaskTransformedParameters
// if it were possible to make ui_TaskMirroredParameters a subclass of
// ui_TaskTransformedParameters
// ---------------------
// Add a context menu to the listview of the originals to delete items
QAction* action = new QAction(tr("Delete"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onOriginalDeleted()));
ui->listFeatures->addAction(action);
ui->listFeatures->setContextMenuPolicy(Qt::ActionsContextMenu);
// Get the feature data
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(getObject());
std::vector<App::DocumentObject*> originals = pcMirrored->Originals.getValues();
// Fill data into dialog elements
ui->listFeatures->setEnabled(true);
ui->listFeatures->clear();
for (std::vector<App::DocumentObject*>::const_iterator i = originals.begin(); i != originals.end(); i++)
{
if ((*i) != NULL)
ui->listFeatures->addItem(QString::fromAscii((*i)->getNameInDocument()));
}
QMetaObject::invokeMethod(ui->listFeatures, "setFocus", Qt::QueuedConnection);
// ---------------------
ui->buttonXY->setEnabled(true);
ui->buttonXZ->setEnabled(true);
ui->buttonYZ->setEnabled(true);
ui->buttonReference->setEnabled(true);
ui->lineReference->setEnabled(false); // This is never enabled since it is for optical feed-back only
updateUI();
}
void TaskMirroredParameters::updateUI()
{
if (updateUIinProgress) return;
updateUIinProgress = true;
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(getObject());
App::DocumentObject* mirrorPlaneFeature = pcMirrored->MirrorPlane.getValue();
std::vector<std::string> mirrorPlanes = pcMirrored->MirrorPlane.getSubValues();
std::string stdMirrorPlane = pcMirrored->StdMirrorPlane.getValue();
if ((featureSelectionMode || insideMultiTransform) && !stdMirrorPlane.empty())
{
ui->buttonReference->setDown(false);
ui->buttonXY->setAutoExclusive(true);
ui->buttonXZ->setAutoExclusive(true);
ui->buttonYZ->setAutoExclusive(true);
ui->buttonXY->setChecked(stdMirrorPlane == "XY");
ui->buttonXZ->setChecked(stdMirrorPlane == "XZ");
ui->buttonYZ->setChecked(stdMirrorPlane == "YZ");
ui->lineReference->setText(tr(""));
} else if ((mirrorPlaneFeature != NULL) && !mirrorPlanes.empty()) {
ui->buttonXY->setAutoExclusive(false);
ui->buttonXZ->setAutoExclusive(false);
ui->buttonYZ->setAutoExclusive(false);
ui->buttonXY->setChecked(false);
ui->buttonXZ->setChecked(false);
ui->buttonYZ->setChecked(false);
ui->buttonReference->setDown(!featureSelectionMode);
ui->lineReference->setText(QString::fromAscii(mirrorPlanes.front().c_str()));
} else {
// Error message?
ui->lineReference->setText(tr(""));
}
updateUIinProgress = false;
}
void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(getObject());
App::DocumentObject* selectedObject = pcMirrored->getDocument()->getActiveObject();
if ((selectedObject == NULL) || !selectedObject->isDerivedFrom(Part::Feature::getClassTypeId()))
return;
if (featureSelectionMode) {
if (originalSelected(msg))
ui->listFeatures->addItem(QString::fromAscii(selectedObject->getNameInDocument()));
} else {
if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string element(msg.pSubName);
if (element.substr(0,4) != "Face")
return;
if (msg.Type == Gui::SelectionChanges::AddSelection) {
std::vector<std::string> mirrorPlanes;
mirrorPlanes.push_back(element.c_str());
pcMirrored->MirrorPlane.setValue(getOriginalObject(), mirrorPlanes);
if (insideMultiTransform) {
if (parentTask->updateView())
recomputeFeature();
} else
if (ui->checkBoxUpdateView->isChecked())
recomputeFeature();
if (!insideMultiTransform)
featureSelectionMode = true; // Jump back to selection of originals
showObject();
hideOriginals();
updateUI();
}
}
}
void TaskMirroredParameters::onOriginalDeleted()
{
int row = ui->listFeatures->currentIndex().row();
TaskTransformedParameters::onOriginalDeleted(row);
ui->listFeatures->model()->removeRow(row);
}
void TaskMirroredParameters::onStdMirrorPlane(const std::string &plane) {
if (updateUIinProgress) return;
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(getObject());
pcMirrored->StdMirrorPlane.setValue(plane.c_str());
pcMirrored->MirrorPlane.setValue(NULL);
if (!insideMultiTransform)
featureSelectionMode = true;
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskMirroredParameters::onButtonXY() {
onStdMirrorPlane("XY");
}
void TaskMirroredParameters::onButtonXZ() {
onStdMirrorPlane("XZ");
}
void TaskMirroredParameters::onButtonYZ() {
onStdMirrorPlane("YZ");
}
void TaskMirroredParameters::onButtonReference()
{
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(getObject());
pcMirrored->StdMirrorPlane.setValue("");
featureSelectionMode = false;
hideObject();
showOriginals();
updateUI();
}
void TaskMirroredParameters::onUpdateView(bool on)
{
ui->buttonXY->blockSignals(!on);
ui->buttonYZ->blockSignals(!on);
ui->buttonXZ->blockSignals(!on);
ui->listFeatures->blockSignals(!on);
}
const std::string TaskMirroredParameters::getStdMirrorPlane(void) const
{
std::string stdMirrorPlane;
if (ui->buttonXY->isChecked())
stdMirrorPlane = "XY";
else if (ui->buttonYZ->isChecked())
stdMirrorPlane = "YZ";
else if (ui->buttonXZ->isChecked())
stdMirrorPlane = "XZ";
if (!stdMirrorPlane.empty())
return std::string("\"") + stdMirrorPlane + "\"";
else
return std::string("");
}
const QString TaskMirroredParameters::getMirrorPlane(void) const
{
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(getObject());
App::DocumentObject* feature = pcMirrored->MirrorPlane.getValue();
if (feature == NULL)
return QString::fromUtf8("");
std::vector<std::string> mirrorPlanes = pcMirrored->MirrorPlane.getSubValues();
QString buf;
if ((feature != NULL) && !mirrorPlanes.empty()) {
buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])");
buf = buf.arg(QString::fromUtf8(feature->getNameInDocument()));
buf = buf.arg(QString::fromUtf8(mirrorPlanes.front().c_str()));
}
else
buf = QString::fromUtf8("");
return buf;
}
TaskMirroredParameters::~TaskMirroredParameters()
{
delete ui;
if (proxy)
delete proxy;
}
void TaskMirroredParameters::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(proxy);
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgMirroredParameters::TaskDlgMirroredParameters(ViewProviderMirrored *MirroredView)
: TaskDlgTransformedParameters(MirroredView)
{
parameter = new TaskMirroredParameters(MirroredView);
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgMirroredParameters::accept()
{
std::string name = TransformedView->getObject()->getNameInDocument();
try {
//Gui::Command::openCommand("Mirrored changed");
// Handle Originals
if (!TaskDlgTransformedParameters::accept())
return false;
TaskMirroredParameters* mirrorParameter = static_cast<TaskMirroredParameters*>(parameter);
std::string mirrorPlane = mirrorParameter->getMirrorPlane().toStdString();
if (!mirrorPlane.empty())
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = %s", name.c_str(), mirrorPlane.c_str());
std::string stdMirrorPlane = mirrorParameter->getStdMirrorPlane();
if (!stdMirrorPlane.empty())
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.StdMirrorPlane = %s",name.c_str(),stdMirrorPlane.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
if (!TransformedView->getObject()->isValid())
throw Base::Exception(TransformedView->getObject()->getStatusString());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return true;
}
#include "moc_TaskMirroredParameters.cpp"

View File

@@ -0,0 +1,101 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 GUI_TASKVIEW_TaskMirroredParameters_H
#define GUI_TASKVIEW_TaskMirroredParameters_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskTransformedParameters.h"
#include "ViewProviderMirrored.h"
class Ui_TaskMirroredParameters;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace PartDesignGui {
class TaskMultiTransformParameters;
class TaskMirroredParameters : public TaskTransformedParameters
{
Q_OBJECT
public:
/// Constructor for task with ViewProvider
TaskMirroredParameters(ViewProviderTransformed *TransformedView, QWidget *parent = 0);
/// Constructor for task with parent task (MultiTransform mode)
TaskMirroredParameters(TaskMultiTransformParameters *parentTask, QLayout *layout);
virtual ~TaskMirroredParameters();
const QString getMirrorPlane(void) const;
const std::string getStdMirrorPlane(void) const;
private Q_SLOTS:
void onButtonXY();
void onButtonXZ();
void onButtonYZ();
virtual void onButtonReference();
virtual void onOriginalDeleted();
virtual void onUpdateView(bool);
protected:
virtual void changeEvent(QEvent *e);
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
private:
void onStdMirrorPlane(const std::string& plane);
void setupUI();
void updateUI();
private:
Ui_TaskMirroredParameters* ui;
};
/// simulation dialog for the TaskView
class TaskDlgMirroredParameters : public TaskDlgTransformedParameters
{
Q_OBJECT
public:
TaskDlgMirroredParameters(ViewProviderMirrored *MirroredView);
virtual ~TaskDlgMirroredParameters() {}
public:
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartDesignGui::TaskPatternRectangularParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskPatternRectangularParameters">
<class>PartDesignGui::TaskMirroredParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskMirroredParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>139</width>
<height>178</height>
<width>218</width>
<height>290</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,74 +15,70 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Spacing1:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBox"/>
</item>
</layout>
<widget class="QListWidget" name="listFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<widget class="QRadioButton" name="buttonXY">
<property name="text">
<string>Number1:</string>
<string>XY</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox"/>
<widget class="QRadioButton" name="buttonXZ">
<property name="text">
<string>XZ</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="buttonYZ">
<property name="text">
<string>YZ</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Second extend</string>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="buttonReference">
<property name="text">
<string>Plane</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineReference"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<widget class="QPushButton" name="buttonOK">
<property name="text">
<string>Spacing2:</string>
<string>OK</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBox_2"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Number2:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_2"/>
</item>
</layout>
<widget class="QCheckBox" name="checkBoxUpdateView">
<property name="text">
<string>Update view</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>

View File

@@ -0,0 +1,503 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMessageBox>
#endif
#include "ui_TaskMultiTransformParameters.h"
#include "TaskMultiTransformParameters.h"
#include "TaskMirroredParameters.h"
#include "TaskLinearPatternParameters.h"
#include "TaskPolarPatternParameters.h"
#include "TaskScaledParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
#include <Mod/PartDesign/App/FeatureMirrored.h>
#include <Mod/PartDesign/App/FeatureLinearPattern.h>
#include <Mod/PartDesign/App/FeaturePolarPattern.h>
#include <Mod/PartDesign/App/FeatureScaled.h>
#include <Mod/Sketcher/App/SketchObject.h>
using namespace PartDesignGui;
using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskMultiTransformParameters */
TaskMultiTransformParameters::TaskMultiTransformParameters(ViewProviderTransformed *TransformedView,QWidget *parent)
: TaskTransformedParameters(TransformedView, parent), subTask(NULL)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskMultiTransformParameters();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
// Create a context menu for the listview of transformation features
QAction* action = new QAction(tr("Edit"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onTransformEdit()));
ui->listTransformFeatures->addAction(action);
action = new QAction(tr("Delete"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onTransformDelete()));
ui->listTransformFeatures->addAction(action);
action = new QAction(tr("Add mirrored transformation"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onTransformAddMirrored()));
ui->listTransformFeatures->addAction(action);
action = new QAction(tr("Add linear pattern"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onTransformAddLinearPattern()));
ui->listTransformFeatures->addAction(action);
action = new QAction(tr("Add polar pattern"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onTransformAddPolarPattern()));
ui->listTransformFeatures->addAction(action);
action = new QAction(tr("Add scaled transformation"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onTransformAddScaled()));
ui->listTransformFeatures->addAction(action);
action = new QAction(tr("Move up"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onMoveUp()));
ui->listTransformFeatures->addAction(action);
action = new QAction(tr("Move down"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onMoveDown()));
ui->listTransformFeatures->addAction(action);
ui->listTransformFeatures->setContextMenuPolicy(Qt::ActionsContextMenu);
connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)),
this, SLOT(onUpdateView(bool)));
connect(ui->listTransformFeatures, SIGNAL(activated(QModelIndex)),
this, SLOT(onTransformActivated(QModelIndex)));
// Get the transformFeatures data
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
// Fill data into dialog elements
ui->listTransformFeatures->setEnabled(true);
ui->listTransformFeatures->clear();
for (std::vector<App::DocumentObject*>::const_iterator i = transformFeatures.begin(); i != transformFeatures.end(); i++)
{
if ((*i) != NULL)
ui->listTransformFeatures->addItem(QString::fromAscii((*i)->Label.getValue()));
}
if (transformFeatures.size() > 0) {
ui->listTransformFeatures->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
editHint = false;
} else {
ui->listTransformFeatures->addItem(tr("Right-click to add"));
editHint = true;
}
// TODO: The following code could be generic in TaskTransformedParameters
// if it were possible to make ui_TaskMultiTransformParameters a subclass of
// ui_TaskTransformedParameters
// ---------------------
// Add a context menu to the listview of the originals to delete items
action = new QAction(tr("Delete"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onOriginalDeleted()));
ui->listFeatures->addAction(action);
ui->listFeatures->setContextMenuPolicy(Qt::ActionsContextMenu);
// Get the Originals data
std::vector<App::DocumentObject*> originals = pcMultiTransform->Originals.getValues();
// Fill data into dialog elements
ui->listFeatures->setEnabled(true);
ui->listFeatures->clear();
for (std::vector<App::DocumentObject*>::const_iterator i = originals.begin(); i != originals.end(); i++)
{
if ((*i) != NULL)
ui->listFeatures->addItem(QString::fromAscii((*i)->getNameInDocument()));
}
QMetaObject::invokeMethod(ui->listFeatures, "setFocus", Qt::QueuedConnection);
// ---------------------
}
void TaskMultiTransformParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
App::DocumentObject* selectedObject = pcMultiTransform->getDocument()->getActiveObject();
if ((selectedObject == NULL) || !selectedObject->isDerivedFrom(Part::Feature::getClassTypeId()))
return;
if (featureSelectionMode) {
if (originalSelected(msg))
ui->listFeatures->addItem(QString::fromAscii(selectedObject->getNameInDocument()));
} else {
// There is no reference that could be selected... must be an error to arrive here at all!
featureSelectionMode = true;
}
}
void TaskMultiTransformParameters::closeSubTask()
{
if (subTask) {
delete subTask;
subTask = NULL;
}
}
void TaskMultiTransformParameters::onTransformDelete()
{
if (editHint) return; // Can't delete the hint...
int row = ui->listTransformFeatures->currentIndex().row();
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
App::DocumentObject* feature = *(transformFeatures.begin() + row);
pcMultiTransform->getDocument()->remObject(feature->getNameInDocument());
closeSubTask();
transformFeatures.erase(transformFeatures.begin() + row);
pcMultiTransform->Transformations.setValues(transformFeatures);
if (ui->checkBoxUpdateView->isChecked())
pcMultiTransform->getDocument()->recomputeFeature(pcMultiTransform);
ui->listTransformFeatures->model()->removeRow(row);
ui->listTransformFeatures->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
}
void TaskMultiTransformParameters::onTransformEdit()
{
if (editHint) return; // Can't edit the hint...
closeSubTask(); // For example if user is editing one subTask and then double-clicks on another without OK'ing first
ui->listTransformFeatures->currentItem()->setSelected(true);
int row = ui->listTransformFeatures->currentIndex().row();
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
subFeature = static_cast<PartDesign::Transformed*>(transformFeatures[row]);
if (transformFeatures[row]->getTypeId() == PartDesign::Mirrored::getClassTypeId())
subTask = new TaskMirroredParameters(this, ui->verticalLayout);
else if (transformFeatures[row]->getTypeId() == PartDesign::LinearPattern::getClassTypeId())
subTask = new TaskLinearPatternParameters(this, ui->verticalLayout);
else if (transformFeatures[row]->getTypeId() == PartDesign::PolarPattern::getClassTypeId())
subTask = new TaskPolarPatternParameters(this, ui->verticalLayout);
else if (transformFeatures[row]->getTypeId() == PartDesign::Scaled::getClassTypeId())
subTask = new TaskScaledParameters(this, ui->verticalLayout);
else
return; // TODO: Show an error?
}
void TaskMultiTransformParameters::onTransformActivated(const QModelIndex& index) {
onTransformEdit();
}
void TaskMultiTransformParameters::onTransformAddMirrored()
{
closeSubTask();
std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("Mirrored");
Gui::Command::openCommand("Mirrored");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",newFeatName.c_str());
Gui::Command::updateActive();
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.StdMirrorPlane = \"XY\"", newFeatName.c_str());
finishAdd(newFeatName);
}
void TaskMultiTransformParameters::onTransformAddLinearPattern()
{
closeSubTask();
std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("LinearPattern");
Gui::Command::openCommand("LinearPattern");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",newFeatName.c_str());
Gui::Command::updateActive();
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.StdDirection = \"X\"", newFeatName.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Length = 100", newFeatName.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str());
finishAdd(newFeatName);
}
void TaskMultiTransformParameters::onTransformAddPolarPattern()
{
closeSubTask();
std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("PolarPattern");
Gui::Command::openCommand("PolarPattern");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",newFeatName.c_str());
Gui::Command::updateActive();
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.StdAxis = \"X\"", newFeatName.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Angle = 360", newFeatName.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str());
finishAdd(newFeatName);
}
void TaskMultiTransformParameters::onTransformAddScaled()
{
closeSubTask();
std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("Scaled");
Gui::Command::openCommand("Scaled");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",newFeatName.c_str());
Gui::Command::updateActive();
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Factor = 2", newFeatName.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str());
finishAdd(newFeatName);
}
void TaskMultiTransformParameters::finishAdd(std::string &newFeatName)
{
//Gui::Command::updateActive();
//Gui::Command::copyVisual(newFeatName.c_str(), "ShapeColor", getOriginals().front()->getNameInDocument().c_str());
//Gui::Command::copyVisual(newFeatName.c_str(), "DisplayMode", getOriginals().front()->getNameInDocument().c_str());
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
if (editHint) {
// Remove hint, first feature is being added
ui->listTransformFeatures->model()->removeRow(0);
}
int row = ui->listTransformFeatures->currentIndex().row();
if (row < 0) {
// Happens when first row (first transformation) is created
row = 0;
// Hide all the originals now (hiding them in Command.cpp presents the user with an empty screen!)
hideOriginals();
}
App::DocumentObject* newFeature = pcMultiTransform->getDocument()->getObject(newFeatName.c_str());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
if (row == ui->listTransformFeatures->model()->rowCount() - 1) {
// Note: Inserts always happen before the specified iterator so in order to append at the
// end we need to use push_back() and append()
transformFeatures.push_back(newFeature);
ui->listTransformFeatures->addItem(QString::fromAscii(newFeature->Label.getValue()));
ui->listTransformFeatures->setCurrentRow(row+1, QItemSelectionModel::ClearAndSelect);
} else {
transformFeatures.insert(transformFeatures.begin() + row, newFeature);
ui->listTransformFeatures->insertItem(row, QString::fromAscii(newFeature->Label.getValue()));
ui->listTransformFeatures->setCurrentRow(row, QItemSelectionModel::ClearAndSelect);
}
pcMultiTransform->Transformations.setValues(transformFeatures);
if (ui->checkBoxUpdateView->isChecked())
pcMultiTransform->getDocument()->recomputeFeature(pcMultiTransform);
// Set state to hidden - only the MultiTransform should be visible
Gui::Command::doCommand(
Gui::Command::Doc,"Gui.activeDocument().getObject(\"%s\").Visibility=False", newFeatName.c_str());
editHint = false;
onTransformEdit();
}
void TaskMultiTransformParameters::moveTransformFeature(const int increment)
{
int row = ui->listTransformFeatures->currentIndex().row();
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
App::DocumentObject* feature = *(transformFeatures.begin() + row);
transformFeatures.erase(transformFeatures.begin() + row);
QListWidgetItem* item = new QListWidgetItem(*(ui->listTransformFeatures->item(row)));
ui->listTransformFeatures->model()->removeRow(row);
// After this operation, if we were to insert at index row again, things will remain unchanged
row += increment;
if (row < 0)
row = 0;
if (row >= ui->listTransformFeatures->model()->rowCount()) {
// Note: Inserts always happen before the specified iterator so in order to append at the
// end we need to use push_back() and append()
transformFeatures.push_back(feature);
ui->listTransformFeatures->addItem(item);
ui->listTransformFeatures->setCurrentRow(row, QItemSelectionModel::ClearAndSelect);
} else {
transformFeatures.insert(transformFeatures.begin() + row, feature);
ui->listTransformFeatures->insertItem(row, item);
ui->listTransformFeatures->setCurrentRow(row, QItemSelectionModel::ClearAndSelect);
}
pcMultiTransform->Transformations.setValues(transformFeatures);
if (ui->checkBoxUpdateView->isChecked())
pcMultiTransform->getDocument()->recomputeFeature(pcMultiTransform);
}
void TaskMultiTransformParameters::onMoveUp()
{
moveTransformFeature(-1);
}
void TaskMultiTransformParameters::onMoveDown()
{
moveTransformFeature(+1);
}
void TaskMultiTransformParameters::onSubTaskButtonOK() {
closeSubTask();
}
void TaskMultiTransformParameters::onOriginalDeleted()
{
int row = ui->listFeatures->currentIndex().row();
TaskTransformedParameters::onOriginalDeleted(row);
ui->listFeatures->model()->removeRow(row);
}
void TaskMultiTransformParameters::onUpdateView(bool on)
{
ui->listFeatures->blockSignals(!on);
}
const std::vector<App::DocumentObject*> TaskMultiTransformParameters::getTransformFeatures(void) const
{
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
return pcMultiTransform->Transformations.getValues();
}
TaskMultiTransformParameters::~TaskMultiTransformParameters()
{
closeSubTask();
delete ui;
if (proxy)
delete proxy;
}
void TaskMultiTransformParameters::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(proxy);
}
}
void TaskMultiTransformParameters::recomputeFeature() {
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
pcMultiTransform->getDocument()->recomputeFeature(pcMultiTransform);
}
const bool TaskMultiTransformParameters::updateView() const
{
return ui->checkBoxUpdateView->isChecked();
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgMultiTransformParameters::TaskDlgMultiTransformParameters(ViewProviderMultiTransform *MultiTransformView)
: TaskDlgTransformedParameters(MultiTransformView)
{
parameter = new TaskMultiTransformParameters(MultiTransformView);
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgMultiTransformParameters::accept()
{
std::string name = TransformedView->getObject()->getNameInDocument();
try {
//Gui::Command::openCommand("MultiTransform changed");
// Handle Originals
if (!TaskDlgTransformedParameters::accept())
return false;
TaskMultiTransformParameters* mtParameter = static_cast<TaskMultiTransformParameters*>(parameter);
std::vector<App::DocumentObject*> transformFeatures = mtParameter->getTransformFeatures();
std::stringstream str;
str << "App.ActiveDocument." << name.c_str() << ".Transformations = [";
for (std::vector<App::DocumentObject*>::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); it++)
{
if ((*it) != NULL)
str << "App.ActiveDocument." << (*it)->getNameInDocument() << ",";
}
str << "]";
Gui::Command::runCommand(Gui::Command::Doc,str.str().c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
if (!TransformedView->getObject()->isValid())
throw Base::Exception(TransformedView->getObject()->getStatusString());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return true;
}
bool TaskDlgMultiTransformParameters::reject()
{
// Get objects before view is invalidated
// For the same reason we can't delegate showing the originals to TaskDlgTransformedParameters::reject()
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> pcOriginals = pcMultiTransform->Originals.getValues();
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
// Delete the transformation features - must happen before abortCommand()!
for (std::vector<App::DocumentObject*>::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); ++it)
{
if ((*it) != NULL)
Gui::Command::doCommand(
Gui::Command::Doc,"App.ActiveDocument.removeObject(\"%s\")", (*it)->getNameInDocument());
}
// roll back the done things
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
// if abort command deleted the object the originals are visible again
if (!Gui::Application::Instance->getViewProvider(pcMultiTransform)) {
for (std::vector<App::DocumentObject*>::const_iterator it = pcOriginals.begin(); it != pcOriginals.end(); ++it)
{
if (((*it) != NULL) && (Gui::Application::Instance->getViewProvider(*it) != NULL)) {
Gui::Application::Instance->getViewProvider(*it)->show();
}
}
}
return true;
}
#include "moc_TaskMultiTransformParameters.cpp"

View File

@@ -0,0 +1,125 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 GUI_TASKVIEW_TaskMultiTransformParameters_H
#define GUI_TASKVIEW_TaskMultiTransformParameters_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskTransformedParameters.h"
#include "ViewProviderMultiTransform.h"
class Ui_TaskMultiTransformParameters;
namespace PartDesign {
class Transformed;
}
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace PartDesignGui {
class TaskMultiTransformParameters : public TaskTransformedParameters
{
Q_OBJECT
public:
TaskMultiTransformParameters(ViewProviderTransformed *TransformedView,QWidget *parent = 0);
virtual ~TaskMultiTransformParameters();
const std::vector<App::DocumentObject*> getTransformFeatures(void) const;
/// Return the currently active subFeature
PartDesign::Transformed* getSubFeature(void) { return subFeature; }
/// Recompute the feature associated with this task
void recomputeFeature();
/// Tell the subtask whether the view should be updated
const bool updateView() const;
private Q_SLOTS:
void onTransformDelete();
void onTransformEdit();
void onTransformActivated(const QModelIndex& index);
void onTransformAddMirrored();
void onTransformAddLinearPattern();
void onTransformAddPolarPattern();
void onTransformAddScaled();
void onMoveUp();
void onMoveDown();
virtual void onButtonReference() {}
virtual void onOriginalDeleted();
virtual void onUpdateView(bool);
/// User finished editing a subFeature
virtual void onSubTaskButtonOK();
// Note: There is no Cancel button because I couldn't work out how to save the state of
// a subFeature so as to revert the changes of an edit operation
protected:
virtual void changeEvent(QEvent *e);
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
private:
void updateUI();
void closeSubTask();
void moveTransformFeature(const int increment);
void finishAdd(std::string &newFeatName);
private:
Ui_TaskMultiTransformParameters* ui;
/// The subTask and subFeature currently active in the UI
TaskTransformedParameters* subTask;
PartDesign::Transformed* subFeature;
bool editHint;
};
/// simulation dialog for the TaskView
class TaskDlgMultiTransformParameters : public TaskDlgTransformedParameters
{
Q_OBJECT
public:
TaskDlgMultiTransformParameters(ViewProviderMultiTransform *MultiTransformView);
virtual ~TaskDlgMultiTransformParameters() {}
public:
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
/// is called by the framework if the dialog is rejected (Cancel)
virtual bool reject();
};
} //namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartDesignGui::TaskMultiTransformParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskMultiTransformParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>559</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Originals</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listFeatures"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Transformations</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listTransformFeatures"/>
</item>
<item>
<widget class="QCheckBox" name="checkBoxUpdateView">
<property name="text">
<string>Update view</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,141 +0,0 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ui_TaskPatternRectangularParameters.h"
#include "TaskPatternRectangularParameters.h"
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
using namespace PartDesignGui;
using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskPatternRectangularParameters */
TaskPatternRectangularParameters::TaskPatternRectangularParameters(QWidget *parent)
: TaskBox(Gui::BitmapFactory().pixmap("document-new"),tr("Parameters rectangular pattern"),true, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskPatternRectangularParameters();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
Gui::Selection().Attach(this);
}
TaskPatternRectangularParameters::~TaskPatternRectangularParameters()
{
delete ui;
Gui::Selection().Detach(this);
}
void TaskPatternRectangularParameters::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(proxy);
}
}
/// @cond DOXERR
void TaskPatternRectangularParameters::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
Gui::SelectionSingleton::MessageType Reason)
{
if (Reason.Type == SelectionChanges::AddSelection ||
Reason.Type == SelectionChanges::RmvSelection ||
Reason.Type == SelectionChanges::SetSelection ||
Reason.Type == SelectionChanges::ClrSelection) {
}
}
/// @endcond
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgPatternRectangularParameters::TaskDlgPatternRectangularParameters(ViewProviderPatternRectangular *PatternRectangularView)
: TaskDialog(),PatternRectangularView(PatternRectangularView)
{
assert(PatternRectangularView);
parameter = new TaskPatternRectangularParameters();
Content.push_back(parameter);
}
TaskDlgPatternRectangularParameters::~TaskDlgPatternRectangularParameters()
{
}
//==== calls from the TaskView ===============================================================
void TaskDlgPatternRectangularParameters::open()
{
}
void TaskDlgPatternRectangularParameters::clicked(int)
{
}
bool TaskDlgPatternRectangularParameters::accept()
{
return true;
}
bool TaskDlgPatternRectangularParameters::reject()
{
Gui::Command::openCommand("PatternRectangular changed");
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
Gui::Command::commitCommand();
return true;
}
void TaskDlgPatternRectangularParameters::helpRequested()
{
}
#include "moc_TaskPatternRectangularParameters.cpp"

View File

@@ -1,108 +0,0 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 GUI_TASKVIEW_TaskPatternRectangularParameters_H
#define GUI_TASKVIEW_TaskPatternRectangularParameters_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "ViewProviderPatternRectangular.h"
class Ui_TaskPatternRectangularParameters;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace PartDesignGui {
class TaskPatternRectangularParameters : public Gui::TaskView::TaskBox, public Gui::SelectionSingleton::ObserverType
{
Q_OBJECT
public:
TaskPatternRectangularParameters(QWidget *parent = 0);
~TaskPatternRectangularParameters();
/// Observer message from the Selection
void OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
Gui::SelectionSingleton::MessageType Reason);
private Q_SLOTS:
protected:
void changeEvent(QEvent *e);
private:
private:
QWidget* proxy;
Ui_TaskPatternRectangularParameters* ui;
};
/// simulation dialog for the TaskView
class TaskDlgPatternRectangularParameters : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDlgPatternRectangularParameters(ViewProviderPatternRectangular *PatternRectangularView);
~TaskDlgPatternRectangularParameters();
ViewProviderPatternRectangular* getPatternRectangularView() const
{ return PatternRectangularView; }
public:
/// is called the TaskView when the dialog is opened
virtual void open();
/// is called by the framework if an button is clicked which has no accept or reject role
virtual void clicked(int);
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
/// is called by the framework if the dialog is rejected (Cancel)
virtual bool reject();
/// is called by the framework if the user presses the help button
virtual void helpRequested();
virtual bool isAllowedAlterDocument(void) const
{ return false; }
/// returns for Close and Help button
virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const
{ return QDialogButtonBox::Close|QDialogButtonBox::Help; }
protected:
ViewProviderPatternRectangular *PatternRectangularView;
TaskPatternRectangularParameters *parameter;
};
} //namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -0,0 +1,436 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMessageBox>
#endif
#include "ui_TaskPolarPatternParameters.h"
#include "TaskPolarPatternParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeaturePolarPattern.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "TaskMultiTransformParameters.h"
using namespace PartDesignGui;
using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskPolarPatternParameters */
TaskPolarPatternParameters::TaskPolarPatternParameters(ViewProviderTransformed *TransformedView,QWidget *parent)
: TaskTransformedParameters(TransformedView, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskPolarPatternParameters();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
ui->buttonOK->hide();
ui->checkBoxUpdateView->setEnabled(true);
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
TaskPolarPatternParameters::TaskPolarPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout)
: TaskTransformedParameters(parentTask)
{
proxy = new QWidget(parentTask);
ui = new Ui_TaskPolarPatternParameters();
ui->setupUi(proxy);
connect(ui->buttonOK, SIGNAL(pressed()),
parentTask, SLOT(onSubTaskButtonOK()));
QMetaObject::connectSlotsByName(this);
layout->addWidget(proxy);
ui->buttonOK->setEnabled(true);
ui->listFeatures->hide();
ui->checkBoxUpdateView->hide();
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
void TaskPolarPatternParameters::setupUI()
{
connect(ui->buttonX, SIGNAL(pressed()),
this, SLOT(onButtonX()));
connect(ui->buttonY, SIGNAL(pressed()),
this, SLOT(onButtonY()));
connect(ui->buttonZ, SIGNAL(pressed()),
this, SLOT(onButtonZ()));
connect(ui->checkReverse, SIGNAL(toggled(bool)),
this, SLOT(onCheckReverse(bool)));
connect(ui->spinAngle, SIGNAL(valueChanged(double)),
this, SLOT(onAngle(double)));
connect(ui->spinOccurrences, SIGNAL(valueChanged(int)),
this, SLOT(onOccurrences(int)));
connect(ui->buttonReference, SIGNAL(pressed()),
this, SLOT(onButtonReference()));
connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)),
this, SLOT(onUpdateView(bool)));
// TODO: The following code could be generic in TaskTransformedParameters
// if it were possible to make ui_TaskPolarPatternParameters a subclass of
// ui_TaskTransformedParameters
// ---------------------
// Add a context menu to the listview of the originals to delete items
QAction* action = new QAction(tr("Delete"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onOriginalDeleted()));
ui->listFeatures->addAction(action);
ui->listFeatures->setContextMenuPolicy(Qt::ActionsContextMenu);
// Get the feature data
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
std::vector<App::DocumentObject*> originals = pcPolarPattern->Originals.getValues();
// Fill data into dialog elements
ui->listFeatures->setEnabled(true);
ui->listFeatures->clear();
for (std::vector<App::DocumentObject*>::const_iterator i = originals.begin(); i != originals.end(); i++)
{
if ((*i) != NULL)
ui->listFeatures->addItem(QString::fromAscii((*i)->getNameInDocument()));
}
QMetaObject::invokeMethod(ui->listFeatures, "setFocus", Qt::QueuedConnection);
// ---------------------
ui->buttonX->setEnabled(true);
ui->buttonY->setEnabled(true);
ui->buttonZ->setEnabled(true);
ui->checkReverse->setEnabled(true);
ui->spinAngle->setEnabled(true);
ui->spinOccurrences->setEnabled(true);
ui->buttonReference->setEnabled(true);
ui->lineReference->setEnabled(false); // This is never enabled since it is for optical feed-back only
updateUI();
}
void TaskPolarPatternParameters::updateUI()
{
if (updateUIinProgress) return;
updateUIinProgress = true;
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
App::DocumentObject* axisFeature = pcPolarPattern->Axis.getValue();
std::vector<std::string> axes = pcPolarPattern->Axis.getSubValues();
std::string stdAxis = pcPolarPattern->StdAxis.getValue();
bool reverse = pcPolarPattern->Reversed.getValue();
double angle = pcPolarPattern->Angle.getValue();
unsigned occurrences = pcPolarPattern->Occurrences.getValue();
if ((featureSelectionMode || insideMultiTransform) && !stdAxis.empty())
{
ui->buttonReference->setDown(false);
ui->buttonX->setAutoExclusive(true);
ui->buttonY->setAutoExclusive(true);
ui->buttonZ->setAutoExclusive(true);
ui->buttonX->setChecked(stdAxis == "X");
ui->buttonY->setChecked(stdAxis == "Y");
ui->buttonZ->setChecked(stdAxis == "Z");
ui->lineReference->setText(tr(""));
} else if ((axisFeature != NULL) && !axes.empty()) {
ui->buttonX->setAutoExclusive(false);
ui->buttonY->setAutoExclusive(false);
ui->buttonZ->setAutoExclusive(false);
ui->buttonX->setChecked(false);
ui->buttonY->setChecked(false);
ui->buttonZ->setChecked(false);
ui->buttonReference->setDown(!featureSelectionMode);
ui->lineReference->setText(QString::fromAscii(axes.front().c_str()));
} else {
// Error message?
ui->lineReference->setText(tr(""));
}
ui->checkReverse->setChecked(reverse);
ui->spinAngle->setValue(angle);
ui->spinOccurrences->setValue(occurrences);
updateUIinProgress = false;
}
void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
App::DocumentObject* selectedObject = pcPolarPattern->getDocument()->getActiveObject();
if ((selectedObject == NULL) || !selectedObject->isDerivedFrom(Part::Feature::getClassTypeId()))
return;
if (featureSelectionMode) {
if (originalSelected(msg))
ui->listFeatures->addItem(QString::fromAscii(selectedObject->getNameInDocument()));
} else {
if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string element(msg.pSubName);
if (msg.Type == Gui::SelectionChanges::AddSelection) {
if (element.substr(0,4) != "Edge")
return;
// TODO
// if (originalElementName == "") {
// Base::Console().Error("Element created by this pattern cannot be used for axis\n");
// return;
// }
std::vector<std::string> axes;
axes.push_back(element.c_str());
pcPolarPattern->Axis.setValue(getOriginalObject(), axes);
if (insideMultiTransform) {
if (parentTask->updateView())
recomputeFeature();
} else
if (ui->checkBoxUpdateView->isChecked())
recomputeFeature();
if (!insideMultiTransform)
featureSelectionMode = true; // Jump back to selection of originals
showObject();
hideOriginals();
updateUI();
}
}
}
void TaskPolarPatternParameters::onOriginalDeleted()
{
int row = ui->listFeatures->currentIndex().row();
TaskTransformedParameters::onOriginalDeleted(row);
ui->listFeatures->model()->removeRow(row);
}
void TaskPolarPatternParameters::onButtonX() {
onStdAxis("X");
}
void TaskPolarPatternParameters::onButtonY() {
onStdAxis("Y");
}
void TaskPolarPatternParameters::onButtonZ() {
onStdAxis("Z");
}
void TaskPolarPatternParameters::onCheckReverse(const bool on) {
if (updateUIinProgress) return;
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
pcPolarPattern->Reversed.setValue(on);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskPolarPatternParameters::onAngle(const double a) {
if (updateUIinProgress) return;
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
pcPolarPattern->Angle.setValue(a);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskPolarPatternParameters::onOccurrences(const int n) {
if (updateUIinProgress) return;
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
pcPolarPattern->Occurrences.setValue(n);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskPolarPatternParameters::onStdAxis(const std::string& axis) {
if (updateUIinProgress) return;
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
pcPolarPattern->StdAxis.setValue(axis.c_str());
pcPolarPattern->Axis.setValue(NULL);
if (!insideMultiTransform)
featureSelectionMode = true;
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskPolarPatternParameters::onButtonReference()
{
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
pcPolarPattern->StdAxis.setValue("");
featureSelectionMode = false;
hideObject();
showOriginals();
updateUI();
}
void TaskPolarPatternParameters::onUpdateView(bool on)
{
ui->buttonX->blockSignals(!on);
ui->buttonY->blockSignals(!on);
ui->buttonZ->blockSignals(!on);
ui->listFeatures->blockSignals(!on);
ui->checkReverse->blockSignals(!on);
ui->spinAngle->blockSignals(!on);
ui->spinOccurrences->blockSignals(!on);
}
const std::string TaskPolarPatternParameters::getStdAxis(void) const
{
std::string stdAxis;
if (ui->buttonX->isChecked())
stdAxis = "X";
else if (ui->buttonY->isChecked())
stdAxis = "Y";
else if (ui->buttonZ->isChecked())
stdAxis = "Z";
if (!stdAxis.empty())
return std::string("\"") + stdAxis + "\"";
else
return std::string("");
}
const QString TaskPolarPatternParameters::getAxis(void) const
{
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(getObject());
App::DocumentObject* feature = pcPolarPattern->Axis.getValue();
if (feature == NULL)
return QString::fromUtf8("");
std::vector<std::string> axes = pcPolarPattern->Axis.getSubValues();
QString buf;
if ((feature != NULL) && !axes.empty()) {
buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])");
buf = buf.arg(QString::fromUtf8(feature->getNameInDocument()));
buf = buf.arg(QString::fromUtf8(axes.front().c_str()));
}
else
buf = QString::fromUtf8("");
return buf;
}
const bool TaskPolarPatternParameters::getReverse(void) const
{
return ui->checkReverse->isChecked();
}
const double TaskPolarPatternParameters::getAngle(void) const
{
return ui->spinAngle->value();
}
const unsigned TaskPolarPatternParameters::getOccurrences(void) const
{
return ui->spinOccurrences->value();
}
TaskPolarPatternParameters::~TaskPolarPatternParameters()
{
delete ui;
if (proxy)
delete proxy;
}
void TaskPolarPatternParameters::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(proxy);
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgPolarPatternParameters::TaskDlgPolarPatternParameters(ViewProviderPolarPattern *PolarPatternView)
: TaskDlgTransformedParameters(PolarPatternView)
{
parameter = new TaskPolarPatternParameters(PolarPatternView);
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgPolarPatternParameters::accept()
{
std::string name = TransformedView->getObject()->getNameInDocument();
try {
//Gui::Command::openCommand("PolarPattern changed");
// Handle Originals
if (!TaskDlgTransformedParameters::accept())
return false;
TaskPolarPatternParameters* polarpatternParameter = static_cast<TaskPolarPatternParameters*>(parameter);
std::string axis = polarpatternParameter->getAxis().toStdString();
if (!axis.empty())
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = %s", name.c_str(), axis.c_str());
std::string stdAxis = polarpatternParameter->getStdAxis();
if (!stdAxis.empty())
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.StdAxis = %s",name.c_str(),stdAxis.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %u",name.c_str(),polarpatternParameter->getReverse());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Angle = %f",name.c_str(),polarpatternParameter->getAngle());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Occurrences = %u",name.c_str(),polarpatternParameter->getOccurrences());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
if (!TransformedView->getObject()->isValid())
throw Base::Exception(TransformedView->getObject()->getStatusString());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return true;
}
#include "moc_TaskPolarPatternParameters.cpp"

View File

@@ -0,0 +1,106 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 GUI_TASKVIEW_TaskPolarPatternParameters_H
#define GUI_TASKVIEW_TaskPolarPatternParameters_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskTransformedParameters.h"
#include "ViewProviderPolarPattern.h"
class Ui_TaskPolarPatternParameters;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace PartDesignGui {
class TaskMultiTransformParameters;
class TaskPolarPatternParameters : public TaskTransformedParameters
{
Q_OBJECT
public:
/// Constructor for task with ViewProvider
TaskPolarPatternParameters(ViewProviderTransformed *TransformedView, QWidget *parent = 0);
/// Constructor for task with parent task (MultiTransform mode)
TaskPolarPatternParameters(TaskMultiTransformParameters *parentTask, QLayout *layout);
virtual ~TaskPolarPatternParameters();
const QString getAxis(void) const;
const std::string getStdAxis(void) const;
const bool getReverse(void) const;
const double getAngle(void) const;
const unsigned getOccurrences(void) const;
private Q_SLOTS:
void onStdAxis(const std::string& axis);
void onButtonX();
void onButtonY();
void onButtonZ();
void onCheckReverse(const bool on);
void onAngle(const double a);
void onOccurrences(const int n);
virtual void onButtonReference();
virtual void onOriginalDeleted();
virtual void onUpdateView(bool);
protected:
virtual void changeEvent(QEvent *e);
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
private:
void updateUI();
void setupUI();
private:
Ui_TaskPolarPatternParameters* ui;
};
/// simulation dialog for the TaskView
class TaskDlgPolarPatternParameters : public TaskDlgTransformedParameters
{
Q_OBJECT
public:
TaskDlgPolarPatternParameters(ViewProviderPolarPattern *PolarPatternView);
virtual ~TaskDlgPolarPatternParameters() {}
public:
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartDesignGui::TaskPolarPatternParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskPolarPatternParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="buttonX">
<property name="text">
<string>X</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="buttonY">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="buttonZ">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QToolButton" name="buttonReference">
<property name="text">
<string>Direction</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineReference"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkReverse">
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Angle</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinAngle">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="value">
<double>360.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Occurrences</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinOccurrences">
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QPushButton" name="buttonOK">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBoxUpdateView">
<property name="text">
<string>Update view</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,261 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMessageBox>
#endif
#include "ui_TaskScaledParameters.h"
#include "TaskScaledParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeatureScaled.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "TaskMultiTransformParameters.h"
using namespace PartDesignGui;
using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskScaledParameters */
TaskScaledParameters::TaskScaledParameters(ViewProviderTransformed *TransformedView,QWidget *parent)
: TaskTransformedParameters(TransformedView, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskScaledParameters();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
ui->buttonOK->hide();
ui->checkBoxUpdateView->setEnabled(true);
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
TaskScaledParameters::TaskScaledParameters(TaskMultiTransformParameters *parentTask, QLayout *layout)
: TaskTransformedParameters(parentTask)
{
proxy = new QWidget(parentTask);
ui = new Ui_TaskScaledParameters();
ui->setupUi(proxy);
connect(ui->buttonOK, SIGNAL(pressed()),
parentTask, SLOT(onSubTaskButtonOK()));
QMetaObject::connectSlotsByName(this);
layout->addWidget(proxy);
ui->buttonOK->setEnabled(true);
ui->listFeatures->hide();
ui->checkBoxUpdateView->hide();
updateUIinProgress = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!!
setupUI();
}
void TaskScaledParameters::setupUI()
{
connect(ui->spinFactor, SIGNAL(valueChanged(double)),
this, SLOT(onFactor(double)));
connect(ui->spinOccurrences, SIGNAL(valueChanged(int)),
this, SLOT(onOccurrences(int)));
connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)),
this, SLOT(onUpdateView(bool)));
// TODO: The following code could be generic in TaskTransformedParameters
// if it were possible to make ui_TaskScaledParameters a subclass of
// ui_TaskTransformedParameters
// ---------------------
// Add a context menu to the listview of the originals to delete items
QAction* action = new QAction(tr("Delete"), ui->listFeatures);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onOriginalDeleted()));
ui->listFeatures->addAction(action);
ui->listFeatures->setContextMenuPolicy(Qt::ActionsContextMenu);
// Get the feature data
PartDesign::Scaled* pcScaled = static_cast<PartDesign::Scaled*>(getObject());
std::vector<App::DocumentObject*> originals = pcScaled->Originals.getValues();
// Fill data into dialog elements
ui->listFeatures->setEnabled(true);
ui->listFeatures->clear();
for (std::vector<App::DocumentObject*>::const_iterator i = originals.begin(); i != originals.end(); i++)
{
if ((*i) != NULL)
ui->listFeatures->addItem(QString::fromAscii((*i)->getNameInDocument()));
}
QMetaObject::invokeMethod(ui->listFeatures, "setFocus", Qt::QueuedConnection);
// ---------------------
ui->spinFactor->setEnabled(true);
ui->spinOccurrences->setEnabled(true);
updateUI();
}
void TaskScaledParameters::updateUI()
{
if (updateUIinProgress) return;
updateUIinProgress = true;
PartDesign::Scaled* pcScaled = static_cast<PartDesign::Scaled*>(getObject());
double factor = pcScaled->Factor.getValue();
unsigned occurrences = pcScaled->Occurrences.getValue();
ui->spinFactor->setValue(factor);
ui->spinOccurrences->setValue(occurrences);
updateUIinProgress = false;
}
void TaskScaledParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
PartDesign::Scaled* pcScaled = static_cast<PartDesign::Scaled*>(getObject());
App::DocumentObject* selectedObject = pcScaled->getDocument()->getActiveObject();
if ((selectedObject == NULL) || !selectedObject->isDerivedFrom(Part::Feature::getClassTypeId()))
return;
if (featureSelectionMode) {
if (originalSelected(msg))
ui->listFeatures->addItem(QString::fromAscii(selectedObject->getNameInDocument()));
} else {
return;
}
}
void TaskScaledParameters::onOriginalDeleted()
{
int row = ui->listFeatures->currentIndex().row();
TaskTransformedParameters::onOriginalDeleted(row);
ui->listFeatures->model()->removeRow(row);
}
void TaskScaledParameters::onFactor(const double f) {
if (updateUIinProgress) return;
PartDesign::Scaled* pcScaled = static_cast<PartDesign::Scaled*>(getObject());
pcScaled->Factor.setValue(f);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskScaledParameters::onOccurrences(const int n) {
if (updateUIinProgress) return;
PartDesign::Scaled* pcScaled = static_cast<PartDesign::Scaled*>(getObject());
pcScaled->Occurrences.setValue(n);
updateUI();
if (insideMultiTransform && !parentTask->updateView())
return;
recomputeFeature();
}
void TaskScaledParameters::onUpdateView(bool on)
{
ui->listFeatures->blockSignals(!on);
ui->spinFactor->blockSignals(!on);
ui->spinOccurrences->blockSignals(!on);
}
const double TaskScaledParameters::getFactor(void) const
{
return ui->spinFactor->value();
}
const unsigned TaskScaledParameters::getOccurrences(void) const
{
return ui->spinOccurrences->value();
}
TaskScaledParameters::~TaskScaledParameters()
{
delete ui;
if (proxy)
delete proxy;
}
void TaskScaledParameters::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(proxy);
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgScaledParameters::TaskDlgScaledParameters(ViewProviderScaled *ScaledView)
: TaskDlgTransformedParameters(ScaledView)
{
parameter = new TaskScaledParameters(ScaledView);
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgScaledParameters::accept()
{
std::string name = TransformedView->getObject()->getNameInDocument();
try {
//Gui::Command::openCommand("Scaled changed");
// Handle Originals
if (!TaskDlgTransformedParameters::accept())
return false;
TaskScaledParameters* scaledParameter = static_cast<TaskScaledParameters*>(parameter);
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Factor = %f",name.c_str(),scaledParameter->getFactor());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Occurrences = %u",name.c_str(),scaledParameter->getOccurrences());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
if (!TransformedView->getObject()->isValid())
throw Base::Exception(TransformedView->getObject()->getStatusString());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return true;
}
#include "moc_TaskScaledParameters.cpp"

View File

@@ -0,0 +1,98 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 GUI_TASKVIEW_TaskScaledParameters_H
#define GUI_TASKVIEW_TaskScaledParameters_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskTransformedParameters.h"
#include "ViewProviderScaled.h"
class Ui_TaskScaledParameters;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace PartDesignGui {
class TaskMultiTransformParameters;
class TaskScaledParameters : public TaskTransformedParameters
{
Q_OBJECT
public:
/// Constructor for task with ViewProvider
TaskScaledParameters(ViewProviderTransformed *TransformedView, QWidget *parent = 0);
/// Constructor for task with parent task (MultiTransform mode)
TaskScaledParameters(TaskMultiTransformParameters *parentTask, QLayout *layout);
virtual ~TaskScaledParameters();
const double getFactor(void) const;
const unsigned getOccurrences(void) const;
private Q_SLOTS:
void onFactor(const double f);
void onOccurrences(const int n);
virtual void onButtonReference() {}
virtual void onOriginalDeleted();
virtual void onUpdateView(bool);
protected:
virtual void changeEvent(QEvent *e);
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
private:
void updateUI();
void setupUI();
private:
Ui_TaskScaledParameters* ui;
};
/// simulation dialog for the TaskView
class TaskDlgScaledParameters : public TaskDlgTransformedParameters
{
Q_OBJECT
public:
TaskDlgScaledParameters(ViewProviderScaled *ScaledView);
virtual ~TaskDlgScaledParameters() {}
public:
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartDesignGui::TaskScaledParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskScaledParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>305</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Factor</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinFactor">
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.500000000000000</double>
</property>
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Occurrences</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinOccurrences">
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="buttonOK">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBoxUpdateView">
<property name="text">
<string>Update view</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,257 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMessageBox>
#endif
#include "TaskTransformedParameters.h"
#include "TaskMultiTransformParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeatureTransformed.h>
#include <Mod/PartDesign/App/FeatureAdditive.h>
#include <Mod/PartDesign/App/FeatureSubtractive.h>
using namespace PartDesignGui;
using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskTransformedParameters */
TaskTransformedParameters::TaskTransformedParameters(ViewProviderTransformed *TransformedView, QWidget *parent)
: TaskBox(Gui::BitmapFactory().pixmap((std::string("PartDesign_") + TransformedView->featureName).c_str()),
QString::fromAscii((TransformedView->featureName + " parameters").c_str()),
true,
parent),
TransformedView(TransformedView),
parentTask(NULL),
insideMultiTransform(false),
updateUIinProgress(false)
{
// Start in feature selection mode
featureSelectionMode = true;
}
TaskTransformedParameters::TaskTransformedParameters(TaskMultiTransformParameters *parentTask)
: TaskBox(QPixmap(), tr(""), true, parentTask),
TransformedView(NULL),
parentTask(parentTask),
insideMultiTransform(true),
updateUIinProgress(false)
{
// Start in reference selection mode and stay there! Feature selection makes
// no sense inside a MultiTransform
featureSelectionMode = false;
}
const bool TaskTransformedParameters::originalSelected(const Gui::SelectionChanges& msg)
{
if (featureSelectionMode && (msg.Type == Gui::SelectionChanges::AddSelection)) {
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(TransformedView->getObject());
App::DocumentObject* selectedObject = pcTransformed->getDocument()->getActiveObject();
if (!selectedObject->isDerivedFrom(PartDesign::Additive::getClassTypeId()) &&
!selectedObject->isDerivedFrom(PartDesign::Subtractive::getClassTypeId()))
return false;
if (TransformedView->getObject() == pcTransformed)
return false;
std::vector<App::DocumentObject*> originals = pcTransformed->Originals.getValues();
if (std::find(originals.begin(), originals.end(), selectedObject) == originals.end()) {
originals.push_back(selectedObject);
pcTransformed->Originals.setValues(originals);
pcTransformed->getDocument()->recomputeFeature(pcTransformed);
return true;
}
}
return false;
}
void TaskTransformedParameters::onOriginalDeleted(const int row)
{
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(TransformedView->getObject());
std::vector<App::DocumentObject*> originals = pcTransformed->Originals.getValues();
originals.erase(originals.begin() + row);
pcTransformed->Originals.setValues(originals);
pcTransformed->getDocument()->recomputeFeature(pcTransformed);
}
PartDesign::Transformed *TaskTransformedParameters::getObject() const
{
if (insideMultiTransform)
return parentTask->getSubFeature();
else
return static_cast<PartDesign::Transformed*>(TransformedView->getObject());
}
void TaskTransformedParameters::recomputeFeature()
{
if (insideMultiTransform) {
parentTask->recomputeFeature();
} else {
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(TransformedView->getObject());
pcTransformed->getDocument()->recomputeFeature(pcTransformed);
}
}
const std::vector<App::DocumentObject*> TaskTransformedParameters::getOriginals(void) const
{
if (insideMultiTransform) {
return parentTask->getOriginals();
} else {
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(TransformedView->getObject());
std::vector<App::DocumentObject*> originals = pcTransformed->Originals.getValues();
return originals;
}
}
App::DocumentObject* TaskTransformedParameters::getOriginalObject() const
{
if (insideMultiTransform) {
return parentTask->getOriginalObject();
} else {
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(TransformedView->getObject());
return pcTransformed->getOriginalObject();
}
}
void TaskTransformedParameters::hideObject()
{
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (doc)
if (insideMultiTransform) {
doc->setHide(parentTask->TransformedView->getObject()->getNameInDocument());
} else {
doc->setHide(TransformedView->getObject()->getNameInDocument());
}
}
void TaskTransformedParameters::showObject()
{
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (doc)
if (insideMultiTransform) {
doc->setShow(parentTask->TransformedView->getObject()->getNameInDocument());
} else {
doc->setShow(TransformedView->getObject()->getNameInDocument());
}
}
void TaskTransformedParameters::hideOriginals()
{
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (doc) {
std::vector<App::DocumentObject*> originals = getOriginals();
for (std::vector<App::DocumentObject*>::iterator it = originals.begin(); it != originals.end(); ++it)
doc->setHide((*it)->getNameInDocument());
}
}
void TaskTransformedParameters::showOriginals()
{
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (doc) {
std::vector<App::DocumentObject*> originals = getOriginals();
for (std::vector<App::DocumentObject*>::iterator it = originals.begin(); it != originals.end(); ++it)
doc->setShow((*it)->getNameInDocument());
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgTransformedParameters::TaskDlgTransformedParameters(ViewProviderTransformed *TransformedView)
: TaskDialog(),TransformedView(TransformedView)
{
assert(TransformedView);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgTransformedParameters::accept()
{
std::string name = TransformedView->getObject()->getNameInDocument();
try {
//Gui::Command::openCommand(featureName + " changed");
std::vector<App::DocumentObject*> originals = parameter->getOriginals();
std::stringstream str;
str << "App.ActiveDocument." << name.c_str() << ".Originals = [";
for (std::vector<App::DocumentObject*>::const_iterator it = originals.begin(); it != originals.end(); ++it)
{
if ((*it) != NULL)
str << "App.ActiveDocument." << (*it)->getNameInDocument() << ",";
}
str << "]";
Gui::Command::runCommand(Gui::Command::Doc,str.str().c_str());
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
// Continue (usually in virtual method accept())
return true;
}
bool TaskDlgTransformedParameters::reject()
{
// Get object before view is invalidated
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(TransformedView->getObject());
std::vector<App::DocumentObject*> pcOriginals = pcTransformed->Originals.getValues();
// roll back the done things
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
// if abort command deleted the object the originals are visible again
if (!Gui::Application::Instance->getViewProvider(pcTransformed)) {
for (std::vector<App::DocumentObject*>::const_iterator it = pcOriginals.begin(); it != pcOriginals.end(); ++it)
{
if (((*it) != NULL) && (Gui::Application::Instance->getViewProvider(*it) != NULL)) {
Gui::Application::Instance->getViewProvider(*it)->show();
}
}
}
return true;
}
#include "moc_TaskTransformedParameters.cpp"

View File

@@ -0,0 +1,145 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 GUI_TASKVIEW_TaskTransformedParameters_H
#define GUI_TASKVIEW_TaskTransformedParameters_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "ViewProviderTransformed.h"
namespace PartDesign {
class Transformed;
}
namespace PartDesignGui {
class TaskMultiTransformParameters;
/**
The transformed subclasses will be used in two different modes:
1. As a stand-alone feature
2. As a container that stores transformation info for a MultiTransform feature. In this case
the flag insideMultiTransform is set to true.
Because in the second case there is no ViewProvider, some special methods are required to
access the underlying FeatureTransformed object in two different ways.
**/
class TaskTransformedParameters : public Gui::TaskView::TaskBox, public Gui::SelectionObserver
{
Q_OBJECT
public:
/// Constructor for task with ViewProvider
TaskTransformedParameters(ViewProviderTransformed *TransformedView, QWidget *parent = 0);
/// Constructor for task with parent task (MultiTransform mode)
TaskTransformedParameters(TaskMultiTransformParameters *parentTask);
virtual ~TaskTransformedParameters()
{}
const std::vector<App::DocumentObject*> getOriginals(void) const;
protected Q_SLOTS:
virtual void onButtonReference() = 0;
virtual void onOriginalDeleted() = 0;
virtual void onUpdateView(bool) = 0;
/// Connect the subTask OK button to the MultiTransform task
virtual void onSubTaskButtonOK() {}
protected:
void onOriginalDeleted(const int row);
const bool originalSelected(const Gui::SelectionChanges& msg);
/// Get the TransformedFeature object associated with this task
// Either through the ViewProvider or the currently active subFeature of the parentTask
PartDesign::Transformed *getObject() const;
/// Recompute either this feature or the parent feature (MultiTransform mode)
void recomputeFeature();
/// Get the original object either of the object associated with this feature or with the parent feature (MultiTransform mode)
App::DocumentObject* getOriginalObject() const;
void hideObject();
void showObject();
void hideOriginals();
void showOriginals();
protected:
virtual void changeEvent(QEvent *e) = 0;
virtual void onSelectionChanged(const Gui::SelectionChanges& msg) = 0;
protected:
QWidget* proxy;
ViewProviderTransformed *TransformedView;
bool featureSelectionMode;
/// The MultiTransform parent task of this task
TaskMultiTransformParameters* parentTask;
/// Flag indicating whether this object is a container for MultiTransform
bool insideMultiTransform;
/// Lock updateUI() so that no unnecessary recomputeFeatures() are triggered
bool updateUIinProgress;
};
/// simulation dialog for the TaskView
class TaskDlgTransformedParameters : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDlgTransformedParameters(ViewProviderTransformed *TransformedView);
virtual ~TaskDlgTransformedParameters() {}
ViewProviderTransformed* getTransformedView() const
{ return TransformedView; }
public:
/// is called the TaskView when the dialog is opened
virtual void open()
{}
/// is called by the framework if an button is clicked which has no accept or reject role
virtual void clicked(int)
{}
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
/// is called by the framework if the dialog is rejected (Cancel)
virtual bool reject();
/// is called by the framework if the user presses the help button
virtual bool isAllowedAlterDocument(void) const
{ return false; }
/// returns for Close and Help button
virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const
{ return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; }
protected:
ViewProviderTransformed *TransformedView;
TaskTransformedParameters *parameter;
};
} //namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -0,0 +1,61 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ViewProviderLinearPattern.h"
#include "TaskLinearPatternParameters.h"
#include <Mod/PartDesign/App/FeatureLinearPattern.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderLinearPattern,PartDesignGui::ViewProvider)
bool ViewProviderLinearPattern::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
TaskDlgLinearPatternParameters *linearpatternDlg = NULL;
if (checkDlgOpen(linearpatternDlg)) {
// start the edit dialog
if (linearpatternDlg)
Gui::Control().showDialog(linearpatternDlg);
else
Gui::Control().showDialog(new TaskDlgLinearPatternParameters(this));
return true;
} else {
return false;
}
}
else {
return ViewProviderPart::setEdit(ModNum);
}
}

View File

@@ -0,0 +1,47 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTGUI_ViewProviderLinearPattern_H
#define PARTGUI_ViewProviderLinearPattern_H
#include "ViewProviderTransformed.h"
namespace PartDesignGui {
class PartDesignGuiExport ViewProviderLinearPattern : public ViewProviderTransformed
{
PROPERTY_HEADER(PartGui::ViewProviderLinearPattern);
public:
ViewProviderLinearPattern()
{ featureName = std::string("LinearPattern"); }
protected:
virtual bool setEdit(int ModNum);
};
} // namespace PartDesignGui
#endif // PARTGUI_ViewProviderLinearPattern_H

View File

@@ -0,0 +1,61 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ViewProviderMirrored.h"
#include "TaskMirroredParameters.h"
#include <Mod/PartDesign/App/FeatureMirrored.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderMirrored,PartDesignGui::ViewProvider)
bool ViewProviderMirrored::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
TaskDlgMirroredParameters *mirroredDlg = NULL;
if (checkDlgOpen(mirroredDlg)) {
// start the edit dialog
if (mirroredDlg)
Gui::Control().showDialog(mirroredDlg);
else
Gui::Control().showDialog(new TaskDlgMirroredParameters(this));
return true;
} else {
return false;
}
}
else {
return ViewProviderPart::setEdit(ModNum);
}
}

View File

@@ -1,43 +1,47 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 *
* *
***************************************************************************/
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef PARTGUI_ViewProviderMirrored_H
#define PARTGUI_ViewProviderMirrored_H
#ifndef _PreComp_
#endif
#include "ViewProviderTransformed.h"
#include "ViewProviderPatternRectangular.h"
namespace PartDesignGui {
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderPatternRectangular,PartDesignGui::ViewProvider)
ViewProviderPatternRectangular::ViewProviderPatternRectangular()
class PartDesignGuiExport ViewProviderMirrored : public ViewProviderTransformed
{
}
PROPERTY_HEADER(PartGui::ViewProviderMirrored);
public:
ViewProviderMirrored()
{ featureName = std::string("Mirrored"); }
ViewProviderPatternRectangular::~ViewProviderPatternRectangular()
{
}
protected:
virtual bool setEdit(int ModNum);
};
} // namespace PartDesignGui
#endif // PARTGUI_ViewProviderMirrored_H

View File

@@ -0,0 +1,92 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ViewProviderMultiTransform.h"
#include "TaskMultiTransformParameters.h"
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderMultiTransform,PartDesignGui::ViewProvider)
bool ViewProviderMultiTransform::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
TaskDlgMultiTransformParameters *multitransformDlg = NULL;
if (checkDlgOpen(multitransformDlg)) {
// start the edit dialog
if (multitransformDlg)
Gui::Control().showDialog(multitransformDlg);
else
Gui::Control().showDialog(new TaskDlgMultiTransformParameters(this));
return true;
} else {
return false;
}
}
else {
return ViewProviderPart::setEdit(ModNum);
}
}
std::vector<App::DocumentObject*> ViewProviderMultiTransform::claimChildren(void) const
{
std::vector<App::DocumentObject*> result = ViewProviderTransformed::claimChildren();
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(getObject());
if (pcMultiTransform == NULL)
return std::vector<App::DocumentObject*>(); // TODO: Show error?
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
result.insert(result.end(), transformFeatures.begin(), transformFeatures.end());
return result;
}
bool ViewProviderMultiTransform::onDelete(const std::vector<std::string> &svec) {
// Delete the transformation features
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
// if abort command deleted the object the transformed features must be deleted, too
for (std::vector<App::DocumentObject*>::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); ++it)
{
if ((*it) != NULL)
Gui::Command::doCommand(
Gui::Command::Doc,"App.ActiveDocument.removeObject(\"%s\")", (*it)->getNameInDocument());
}
// Handle Originals
return ViewProviderTransformed::onDelete(svec);
}

View File

@@ -0,0 +1,51 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTGUI_ViewProviderMultiTransform_H
#define PARTGUI_ViewProviderMultiTransform_H
#include "ViewProviderTransformed.h"
namespace PartDesignGui {
class PartDesignGuiExport ViewProviderMultiTransform : public ViewProviderTransformed
{
PROPERTY_HEADER(PartGui::ViewProviderMultiTransform);
public:
ViewProviderMultiTransform()
{ featureName = std::string("MultiTransform"); }
std::vector<App::DocumentObject*> claimChildren(void) const;
virtual bool onDelete(const std::vector<std::string> &);
protected:
virtual bool setEdit(int ModNum);
};
} // namespace PartDesignGui
#endif // PARTGUI_ViewProviderMultiTransform_H

View File

@@ -0,0 +1,61 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ViewProviderPolarPattern.h"
#include "TaskPolarPatternParameters.h"
#include <Mod/PartDesign/App/FeaturePolarPattern.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderPolarPattern,PartDesignGui::ViewProvider)
bool ViewProviderPolarPattern::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
TaskDlgPolarPatternParameters *polarpatternDlg = NULL;
if (checkDlgOpen(polarpatternDlg)) {
// start the edit dialog
if (polarpatternDlg)
Gui::Control().showDialog(polarpatternDlg);
else
Gui::Control().showDialog(new TaskDlgPolarPatternParameters(this));
return true;
} else {
return false;
}
}
else {
return ViewProviderPart::setEdit(ModNum);
}
}

View File

@@ -0,0 +1,47 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTGUI_ViewProviderPolarPattern_H
#define PARTGUI_ViewProviderPolarPattern_H
#include "ViewProviderTransformed.h"
namespace PartDesignGui {
class PartDesignGuiExport ViewProviderPolarPattern : public ViewProviderTransformed
{
PROPERTY_HEADER(PartGui::ViewProviderPolarPattern);
public:
ViewProviderPolarPattern()
{ featureName = std::string("PolarPattern"); }
protected:
virtual bool setEdit(int ModNum);
};
} // namespace PartDesignGui
#endif // PARTGUI_ViewProviderPolarPattern_H

View File

@@ -0,0 +1,61 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ViewProviderScaled.h"
#include "TaskScaledParameters.h"
#include <Mod/PartDesign/App/FeatureScaled.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderScaled,PartDesignGui::ViewProvider)
bool ViewProviderScaled::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
TaskDlgScaledParameters *scaledDlg = NULL;
if (checkDlgOpen(scaledDlg)) {
// start the edit dialog
if (scaledDlg)
Gui::Control().showDialog(scaledDlg);
else
Gui::Control().showDialog(new TaskDlgScaledParameters(this));
return true;
} else {
return false;
}
}
else {
return ViewProviderPart::setEdit(ModNum);
}
}

View File

@@ -1,43 +1,42 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 *
* *
***************************************************************************/
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTGUI_ViewProviderPatternRectangular_H
#define PARTGUI_ViewProviderPatternRectangular_H
#include "ViewProvider.h"
#ifndef PARTGUI_ViewProviderScaled_H
#define PARTGUI_ViewProviderScaled_H
#include "ViewProviderTransformed.h"
namespace PartDesignGui {
class PartDesignGuiExport ViewProviderPatternRectangular : public ViewProvider
class PartDesignGuiExport ViewProviderScaled : public ViewProviderTransformed
{
PROPERTY_HEADER(PartGui::ViewProviderPatternRectangular);
PROPERTY_HEADER(PartGui::ViewProviderScaled);
public:
/// constructor
ViewProviderPatternRectangular();
/// destructor
virtual ~ViewProviderPatternRectangular();
ViewProviderScaled()
{ featureName = std::string("Scaled"); }
protected:
virtual bool setEdit(int ModNum);
};
@@ -45,4 +44,4 @@ public:
} // namespace PartDesignGui
#endif // PARTGUI_ViewProviderPad_H
#endif // PARTGUI_ViewProviderScaled_H

View File

@@ -0,0 +1,114 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 *
* *
******************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ViewProviderTransformed.h"
#include "TaskTransformedParameters.h"
#include <Mod/PartDesign/App/FeatureTransformed.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderTransformed,PartDesignGui::ViewProvider)
std::vector<App::DocumentObject*> ViewProviderTransformed::claimChildren(void)const
{
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(getObject());
if (pcTransformed == NULL)
return std::vector<App::DocumentObject*>(); // TODO: Show error?
std::vector<App::DocumentObject*> originals = pcTransformed->Originals.getValues();
return originals;
}
void ViewProviderTransformed::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
QAction* act;
act = menu->addAction(QObject::tr((std::string("Edit ") + featureName + " feature").c_str()), receiver, member);
act->setData(QVariant((int)ViewProvider::Default));
PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member);
}
void ViewProviderTransformed::unsetEdit(int ModNum)
{
if (ModNum == ViewProvider::Default) {
// when pressing ESC make sure to close the dialog
Gui::Control().closeDialog();
}
else {
PartGui::ViewProviderPart::unsetEdit(ModNum);
}
}
bool ViewProviderTransformed::onDelete(const std::vector<std::string> &)
{
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(getObject());
std::vector<App::DocumentObject*> originals = pcTransformed->Originals.getValues();
// if abort command deleted the object the originals are visible again
for (std::vector<App::DocumentObject*>::const_iterator it = originals.begin(); it != originals.end(); ++it)
{
if (((*it) != NULL) && Gui::Application::Instance->getViewProvider(*it))
Gui::Application::Instance->getViewProvider(*it)->show();
}
return true;
}
const bool ViewProviderTransformed::checkDlgOpen(TaskDlgTransformedParameters* transformedDlg) {
// When double-clicking on the item for this feature the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
transformedDlg = qobject_cast<TaskDlgTransformedParameters *>(dlg);
if ((transformedDlg != NULL) && (transformedDlg->getTransformedView() != this))
transformedDlg = NULL; // another transformed feature left open its task panel
if ((dlg != NULL) && (transformedDlg == NULL)) {
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().closeDialog();
else
return false;
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
// Continue (usually in virtual method setEdit())
return true;
}

View File

@@ -0,0 +1,65 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 PARTGUI_ViewProviderTransformed_H
#define PARTGUI_ViewProviderTransformed_H
#include "ViewProvider.h"
namespace PartDesignGui {
class TaskDlgTransformedParameters;
class PartDesignGuiExport ViewProviderTransformed : public ViewProvider
{
PROPERTY_HEADER(PartGui::ViewProviderTransformed);
public:
/// constructor
ViewProviderTransformed()
: featureName("undefined") {}
/// destructor
virtual ~ViewProviderTransformed()
{}
/// grouping handling
std::vector<App::DocumentObject*> claimChildren(void) const;
void setupContextMenu(QMenu*, QObject*, const char*);
virtual bool onDelete(const std::vector<std::string> &);
// The feature name of the subclass
std::string featureName;
protected:
virtual bool setEdit(int ModNum) { return false; }
virtual void unsetEdit(int ModNum);
const bool checkDlgOpen(TaskDlgTransformedParameters* transformedDlg);
};
} // namespace PartDesignGui
#endif // PARTGUI_ViewProviderTransformed_H

View File

@@ -95,6 +95,20 @@ void Workbench::activated()
"Part_Box"
));
const char* Transformed[] = {
"PartDesign_Mirrored",
"PartDesign_LinearPattern",
"PartDesign_PolarPattern",
// "PartDesign_Scaled",
"PartDesign_MultiTransform",
0};
Watcher.push_back(new Gui::TaskView::TaskWatcherCommands(
"SELECT Part::Feature",
Transformed,
"Transformation tools",
"PartDesign_Mirrored"
));
const char* Empty[] = {
"Sketcher_NewSketch",
"Part_Box",
@@ -172,7 +186,12 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "PartDesign_Revolution"
<< "PartDesign_Groove"
<< "PartDesign_Fillet"
<< "PartDesign_Chamfer";
<< "PartDesign_Chamfer"
<< "PartDesign_Mirrored"
<< "PartDesign_LinearPattern"
<< "PartDesign_PolarPattern"
// << "PartDesign_Scaled"
<< "PartDesign_MultiTransform";
return root;
}
@@ -190,7 +209,12 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "PartDesign_Revolution"
<< "PartDesign_Groove"
<< "PartDesign_Fillet"
<< "PartDesign_Chamfer";
<< "PartDesign_Chamfer"
<< "PartDesign_Mirrored"
<< "PartDesign_LinearPattern"
<< "PartDesign_PolarPattern"
// << "PartDesign_Scaled"
<< "PartDesign_MultiTransform";
part = new Gui::ToolBarItem(root);
part->setCommand("Sketcher geometries");