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

This commit is contained in:
wmayer 2013-02-14 17:41:44 +01:00
commit 8079e6452b
17 changed files with 596 additions and 150 deletions

View File

@ -80,6 +80,8 @@ class _Site(ArchFloor._Floor):
"The Site object"
def __init__(self,obj):
ArchFloor._Floor.__init__(self,obj)
obj.addProperty("App::PropertyLink","Terrain","Base",
str(translate("Arch","The terrain of this site")))
self.Type = "Site"
obj.setEditorMode('Height',2)
@ -91,6 +93,9 @@ class _ViewProviderSite(ArchFloor._ViewProviderFloor):
def getIcon(self):
import Arch_rc
return ":/icons/Arch_Site_Tree.svg"
def claimChildren(self):
return self.Object.Group+[self.Object.Terrain]
FreeCADGui.addCommand('Arch_Site',_CommandSite())

View File

@ -113,6 +113,7 @@ def read(filename):
# parsing the IFC file
t1 = time.time()
schema=getSchema()
ifcRel = {}
if schema:
if DEBUG: global ifc
if DEBUG: print "opening",filename,"..."
@ -140,45 +141,57 @@ def read(filename):
# retrieving name
n = obj.name
if not n:
n = "Unnamed"
n = ""
# build shape
shape = None
if useShapes:
shape = getShape(obj)
# skip types
if obj.type in SKIP:
pass
# walls
elif obj.type == "IfcWallStandardCase":
makeWall(ifc.Entities[obj.id],shape)
nobj = makeWall(ifc.Entities[obj.id],shape,n)
# windows
elif obj.type in ["IfcWindow","IfcDoor"]:
makeWindow(ifc.Entities[obj.id],shape)
nobj = makeWindow(ifc.Entities[obj.id],shape,n)
# structs
elif obj.type in ["IfcBeam","IfcColumn","IfcSlab"]:
makeStructure(ifc.Entities[obj.id],shape)
elif obj.type in ["IfcBeam","IfcColumn","IfcSlab","IfcFooting"]:
nobj = makeStructure(ifc.Entities[obj.id],shape,n)
# furniture
elif obj.type == "IfcFurnishingElement":
nobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Furniture")
nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n)
nobj.Shape = shape
elif shape:
# treat as dumb parts
if not n:
n = "Unnamed"
nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n)
nobj.Shape = shape
else:
# treat as meshes
if not n:
n = "Unnamed"
me,pl = getMesh(obj)
nobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n)
nobj.Mesh = me
nobj.Placement = pl
ifcRel[obj.id] = nobj
# mark terrain objects so they can be associated to sites
if obj.type == "IfcSite":
if not "terrains" in ifcRel:
ifcRel["terrains"] = []
ifcRel["terrains"].append([obj.id,nobj])
if not IfcImport.Next():
break
@ -190,37 +203,41 @@ def read(filename):
# getting walls
for w in ifc.getEnt("IfcWallStandardCase"):
makeWall(w)
nobj = makeWall(w)
ifcRel[w.id] = nobj
# getting windows and doors
for w in (ifc.getEnt("IfcWindow") + ifc.getEnt("IfcDoor")):
makeWindow(w)
nobj = makeWindow(w)
ifcRel[w.id] = nobj
# getting structs
for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") + ifc.getEnt("IfcColumn")):
makeStructure(w)
for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") + ifc.getEnt("IfcColumn") \
+ ifc.getEnt("IfcFooting")):
nobj = makeStructure(w)
ifcRel[w.id] = nobj
order(ifc)
order(ifc,ifcRel)
FreeCAD.ActiveDocument.recompute()
t3 = time.time()
if DEBUG: print "done processing",ifc,"in %s s" % ((t3-t1))
return None
def order(ifc):
def order(ifc,ifcRel):
"orders the already generated elements by building and by floor"
# getting floors
for f in ifc.getEnt("IfcBuildingStorey"):
group(f,"Floor")
group(f,ifcRel,"Floor")
# getting buildings
for b in ifc.getEnt("IfcBuilding"):
group(b,"Building")
group(b,ifcRel,"Building")
# getting sites
for s in ifc.getEnt("IfcSite"):
group(s,"Site")
group(s,ifcRel,"Site")
def group(entity,mode=None):
def group(entity,ifcRel,mode=None):
"gathers the children of the given entity"
try:
@ -246,22 +263,21 @@ def group(entity,mode=None):
elts.extend(s)
print "found dependent elements: ",elts
groups = [['Wall','IfcWallStandardCase',[]],
['Window','IfcWindow',[]],
['Door','IfcDoor',[]],
['Slab','IfcSlab',[]],
['Beam','IfcBeam',[]],
['Column','IfcColumn',[]],
['Floor','IfcBuildingStorey',[]],
['Building','IfcBuilding',[]],
['Furniture','IfcFurnishingElement',[]]]
groups = [['Wall',['IfcWallStandardCase'],[]],
['Window',['IfcWindow','IfcDoor'],[]],
['Structure',['IfcSlab','IfcFooting','IfcBeam','IfcColumn'],[]],
['Floor',['IfcBuildingStorey'],[]],
['Building',['IfcBuilding'],[]],
['Furniture',['IfcFurnishingElement'],[]]]
for e in elts:
for g in groups:
if e.type.upper() == g[1].upper():
o = FreeCAD.ActiveDocument.getObject(g[0] + str(e.id))
if o:
g[2].append(o)
for t in g[1]:
if e.type.upper() == t.upper():
if e.id in ifcRel:
g[2].append(ifcRel[e.id])
elif hasattr(FreeCAD.ActiveDocument,g[0]+str(e.id)):
g[2].append(FreeCAD.ActiveDocument.getObject(g[0]+str(e.id)))
print "groups:",groups
comps = []
@ -280,26 +296,39 @@ def group(entity,mode=None):
for g in groups:
comps.extend(g[2])
label = entity.Name
name = mode + str(entity.id)
cell = None
if mode == "Site":
cell = Arch.makeSite(comps,name=name)
# add terrain object
if "terrains" in ifcRel:
for t in ifcRel["terrains"]:
if t[0] == entity.id:
if not t[1] in comps:
cell.Terrain = t[1]
elif mode == "Floor":
cell = Arch.makeFloor(comps,name=name)
elif mode == "Building":
cell = Arch.makeBuilding(comps,name=name)
if label and cell:
cell.Label = label
except:
if DEBUG: print "error: skipping group ",entity.id
def makeWall(entity,shape=None):
def makeWall(entity,shape=None,name=None):
"makes a wall in the freecad document"
try:
if DEBUG: print "=====> making wall",entity.id
if shape:
# use ifcopenshell
sh = FreeCAD.ActiveDocument.addObject("Part::Feature","WallBody")
sh.Shape = shape
wall = Arch.makeWall(sh,name="Wall"+str(entity.id))
wall.Label = name
if DEBUG: print "made wall object ",entity.id,":",wall
return
return wall
# use internal parser
placement = wall = wire = body = width = height = None
placement = getPlacement(entity.ObjectPlacement)
if DEBUG: print "got wall placement",entity.id,":",placement
@ -311,6 +340,8 @@ def makeWall(entity,shape=None):
if r.RepresentationIdentifier == "Axis":
wire = getWire(r.Items,placement)
wall = Arch.makeWall(wire,width,height,align="Center",name="Wall"+str(entity.id))
if name:
wall.Label = name
else:
if DEBUG: print "no height or width properties found..."
for r in entity.Representation.Representations:
@ -324,19 +355,28 @@ def makeWall(entity,shape=None):
wall.Normal = norm
if wall:
if DEBUG: print "made wall object ",entity.id,":",wall
return wall
if DEBUG: print "error: skipping wall",entity.id
return None
except:
if DEBUG: print "error: skipping wall",entity.id
return None
def makeWindow(entity,shape=None):
def makeWindow(entity,shape=None,name=""):
"makes a window in the freecad document"
try:
typ = "Window" if entity.type == "IFCWINDOW" else "Door"
if DEBUG: print "=====> making window",entity.id
if shape:
# use ifcopenshell
window = Arch.makeWindow(name=typ+str(entity.id))
window.Shape = shape
if name:
window.Label = name
if DEBUG: print "made window object ",entity.id,":",window
return
return window
# use internal parser
placement = window = wire = body = width = height = None
placement = getPlacement(entity.ObjectPlacement)
if DEBUG: print "got window placement",entity.id,":",placement
@ -350,26 +390,36 @@ def makeWindow(entity,shape=None):
window = Arch.makeWindow(wire,width=b.Depth,name=typ+str(entity.id))
if window:
if DEBUG: print "made window object ",entity.id,":",window
return window
if DEBUG: print "error: skipping window",entity.id
return None
except:
if DEBUG: print "error: skipping window",entity.id
return None
def makeStructure(entity,shape=None):
def makeStructure(entity,shape=None,name=""):
"makes a structure in the freecad document"
try:
if entity.type == "IFCSLAB":
typ = "Slab"
elif entity.type == "IFCBEAM":
typ = "Beam"
elif entity.type == "IFCFOOTING":
typ = "Footing"
else:
typ = "Column"
if DEBUG: print "=====> making struct",entity.id
if shape:
# use ifcopenshell
sh = FreeCAD.ActiveDocument.addObject("Part::Feature","StructureBody")
sh.Shape = shape
structure = Arch.makeStructure(sh,name=typ+str(entity.id))
if name:
structure.Label = name
if DEBUG: print "made structure object ",entity.id,":",structure
return
return structure
# use internal parser
placement = structure = wire = body = width = height = None
placement = getPlacement(entity.ObjectPlacement)
if DEBUG: print "got window placement",entity.id,":",placement
@ -383,10 +433,13 @@ def makeStructure(entity,shape=None):
structure = Arch.makeStructure(wire,height=b.Depth,name=typ+str(entity.id))
if structure:
if DEBUG: print "made structure object ",entity.id,":",structure
return structure
if DEBUG: print "error: skipping structure",entity.id
return None
except:
if DEBUG: print "error: skipping structure",entity.id
return None
# geometry helpers ###################################################################
def getMesh(obj):

View File

@ -162,30 +162,10 @@ void Part2DObject::positionBySupport(void)
gp_Trsf Trf;
Trf.SetTransformation(SketchPos);
Trf.Invert();
Trf.SetScaleFactor(Standard_Real(1.0));
Base::Matrix4D mtrx;
gp_Mat m = Trf._CSFDB_Getgp_Trsfmatrix();
gp_XYZ p = Trf._CSFDB_Getgp_Trsfloc();
Standard_Real scale = 1.0;
// set Rotation matrix
mtrx[0][0] = scale * m._CSFDB_Getgp_Matmatrix(0,0);
mtrx[0][1] = scale * m._CSFDB_Getgp_Matmatrix(0,1);
mtrx[0][2] = scale * m._CSFDB_Getgp_Matmatrix(0,2);
mtrx[1][0] = scale * m._CSFDB_Getgp_Matmatrix(1,0);
mtrx[1][1] = scale * m._CSFDB_Getgp_Matmatrix(1,1);
mtrx[1][2] = scale * m._CSFDB_Getgp_Matmatrix(1,2);
mtrx[2][0] = scale * m._CSFDB_Getgp_Matmatrix(2,0);
mtrx[2][1] = scale * m._CSFDB_Getgp_Matmatrix(2,1);
mtrx[2][2] = scale * m._CSFDB_Getgp_Matmatrix(2,2);
// set pos vector
mtrx[0][3] = p._CSFDB_Getgp_XYZx();
mtrx[1][3] = p._CSFDB_Getgp_XYZy();
mtrx[2][3] = p._CSFDB_Getgp_XYZz();
TopoShape::convertToMatrix(Trf,mtrx);
// check the angle against the Z Axis
//Standard_Real a = Normal.Angle(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1)));

View File

@ -34,6 +34,8 @@
# include <BRepAlgoAPI_Cut.hxx>
# include <Precision.hxx>
# include <gp_Lin.hxx>
# include <GProp_GProps.hxx>
# include <BRepGProp.hxx>
#endif
#include <Base/Axis.h>
@ -83,49 +85,17 @@ App::DocumentObjectExecReturn *Groove::execute(void)
if (Reversed.getValue() && !Midplane.getValue())
angle *= (-1.0);
Part::Part2DObject* sketch = 0;
std::vector<TopoDS_Wire> wires;
TopoDS_Shape support;
try {
sketch = getVerifiedSketch();
wires = getSketchWires();
support = getSupportShape();
} catch (const Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what());
}
// get the Sketch plane
Base::Placement SketchPlm = sketch->Placement.getValue();
// get reference axis
App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue();
const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
if (pcReferenceAxis && pcReferenceAxis == sketch) {
bool hasValidAxis=false;
Base::Axis axis;
if (subReferenceAxis[0] == "V_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::V_Axis);
}
else if (subReferenceAxis[0] == "H_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::H_Axis);
}
else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") {
int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str());
if (AxId >= 0 && AxId < sketch->getAxisCount()) {
hasValidAxis = true;
axis = sketch->getAxis(AxId);
}
}
if (hasValidAxis) {
axis *= SketchPlm;
Base::Vector3d base=axis.getBase();
Base::Vector3d dir=axis.getDirection();
Base.setValue(base.x,base.y,base.z);
Axis.setValue(dir.x,dir.y,dir.z);
}
}
// update Axis from ReferenceAxis
updateAxis();
// get revolve axis
Base::Vector3f b = Base.getValue();
@ -196,4 +166,77 @@ App::DocumentObjectExecReturn *Groove::execute(void)
}
}
bool Groove::suggestReversed(void)
{
try {
updateAxis();
Part::Part2DObject* sketch = getVerifiedSketch();
std::vector<TopoDS_Wire> wires = getSketchWires();
TopoDS_Shape sketchshape = makeFace(wires);
Base::Vector3f b = Base.getValue();
Base::Vector3f v = Axis.getValue();
// get centre of gravity of the sketch face
GProp_GProps props;
BRepGProp::SurfaceProperties(sketchshape, props);
gp_Pnt cog = props.CentreOfMass();
Base::Vector3f p_cog(cog.X(), cog.Y(), cog.Z());
// get direction to cog from its projection on the revolve axis
Base::Vector3f perp_dir = p_cog - p_cog.Perpendicular(b, v);
// get cross product of projection direction with revolve axis direction
Base::Vector3f cross = v % perp_dir;
// get sketch vector pointing away from support material
Base::Placement SketchPos = sketch->Placement.getValue();
Base::Rotation SketchOrientation = SketchPos.getRotation();
Base::Vector3d SketchNormal(0,0,1);
SketchOrientation.multVec(SketchNormal,SketchNormal);
// simply convert double to float
Base::Vector3f norm(SketchNormal.x, SketchNormal.y, SketchNormal.z);
// return true if the angle between norm and cross is acute
return norm * cross > 0.f;
}
catch (...) {
return Reversed.getValue();
}
}
void Groove::updateAxis(void)
{
Part::Part2DObject* sketch = getVerifiedSketch();
Base::Placement SketchPlm = sketch->Placement.getValue();
// get reference axis
App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue();
const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
if (pcReferenceAxis && pcReferenceAxis == sketch) {
bool hasValidAxis=false;
Base::Axis axis;
if (subReferenceAxis[0] == "V_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::V_Axis);
}
else if (subReferenceAxis[0] == "H_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::H_Axis);
}
else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") {
int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str());
if (AxId >= 0 && AxId < sketch->getAxisCount()) {
hasValidAxis = true;
axis = sketch->getAxis(AxId);
}
}
if (hasValidAxis) {
axis *= SketchPlm;
Base::Vector3d base=axis.getBase();
Base::Vector3d dir=axis.getDirection();
Base.setValue(base.x,base.y,base.z);
Axis.setValue(dir.x,dir.y,dir.z);
}
}
}
}

View File

@ -62,6 +62,12 @@ public:
return "PartDesignGui::ViewProviderGroove";
}
//@}
/// suggests a value for Reversed flag so that material is always removed from the support
bool suggestReversed(void);
protected:
/// updates Axis from ReferenceAxis
void updateAxis(void);
};
} //namespace PartDesign

View File

@ -34,6 +34,8 @@
# include <BRepAlgoAPI_Fuse.hxx>
# include <Precision.hxx>
# include <gp_Lin.hxx>
# include <GProp_GProps.hxx>
# include <BRepGProp.hxx>
#endif
#include <Base/Axis.h>
@ -41,7 +43,6 @@
#include <Base/Tools.h>
#include "FeatureRevolution.h"
#include <Base/Console.h>
using namespace PartDesign;
@ -75,19 +76,17 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
// Validate parameters
double angle = Angle.getValue();
if (angle < Precision::Confusion())
return new App::DocumentObjectExecReturn("Angle of groove too small");
return new App::DocumentObjectExecReturn("Angle of revolution too small");
if (angle > 360.0)
return new App::DocumentObjectExecReturn("Angle of groove too large");
return new App::DocumentObjectExecReturn("Angle of revolution too large");
angle = Base::toRadians<double>(angle);
// Reverse angle if selected
if (Reversed.getValue() && !Midplane.getValue())
angle *= (-1.0);
Part::Part2DObject* sketch = 0;
std::vector<TopoDS_Wire> wires;
try {
sketch = getVerifiedSketch();
wires = getSketchWires();
} catch (const Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what());
@ -101,41 +100,8 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
support = TopoDS_Shape();
}
// get the Sketch plane
Base::Placement SketchPlm = sketch->Placement.getValue();
// get reference axis
App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue();
const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
bool hasValidAxis=false;
if (pcReferenceAxis && pcReferenceAxis == sketch) {
Base::Axis axis;
if (subReferenceAxis[0] == "V_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::V_Axis);
}
else if (subReferenceAxis[0] == "H_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::H_Axis);
}
else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") {
int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str());
if (AxId >= 0 && AxId < sketch->getAxisCount()) {
hasValidAxis = true;
axis = sketch->getAxis(AxId);
}
}
if (hasValidAxis) {
axis *= SketchPlm;
Base::Vector3d base=axis.getBase();
Base::Vector3d dir=axis.getDirection();
Base.setValue(base.x,base.y,base.z);
Axis.setValue(dir.x,dir.y,dir.z);
}
}
if (!hasValidAxis) {
return new App::DocumentObjectExecReturn("No valid reference axis defined");
}
// update Axis from ReferenceAxis
updateAxis();
// get revolve axis
Base::Vector3f b = Base.getValue();
@ -204,5 +170,78 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
return new App::DocumentObjectExecReturn(e.what());
}
}
bool Revolution::suggestReversed(void)
{
try {
updateAxis();
Part::Part2DObject* sketch = getVerifiedSketch();
std::vector<TopoDS_Wire> wires = getSketchWires();
TopoDS_Shape sketchshape = makeFace(wires);
Base::Vector3f b = Base.getValue();
Base::Vector3f v = Axis.getValue();
// get centre of gravity of the sketch face
GProp_GProps props;
BRepGProp::SurfaceProperties(sketchshape, props);
gp_Pnt cog = props.CentreOfMass();
Base::Vector3f p_cog(cog.X(), cog.Y(), cog.Z());
// get direction to cog from its projection on the revolve axis
Base::Vector3f perp_dir = p_cog - p_cog.Perpendicular(b, v);
// get cross product of projection direction with revolve axis direction
Base::Vector3f cross = v % perp_dir;
// get sketch vector pointing away from support material
Base::Placement SketchPos = sketch->Placement.getValue();
Base::Rotation SketchOrientation = SketchPos.getRotation();
Base::Vector3d SketchNormal(0,0,1);
SketchOrientation.multVec(SketchNormal,SketchNormal);
// simply convert double to float
Base::Vector3f norm(SketchNormal.x, SketchNormal.y, SketchNormal.z);
// return true if the angle between norm and cross is obtuse
return norm * cross < 0.f;
}
catch (...) {
return Reversed.getValue();
}
}
void Revolution::updateAxis(void)
{
Part::Part2DObject* sketch = getVerifiedSketch();
Base::Placement SketchPlm = sketch->Placement.getValue();
// get reference axis
App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue();
const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
if (pcReferenceAxis && pcReferenceAxis == sketch) {
bool hasValidAxis=false;
Base::Axis axis;
if (subReferenceAxis[0] == "V_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::V_Axis);
}
else if (subReferenceAxis[0] == "H_Axis") {
hasValidAxis = true;
axis = sketch->getAxis(Part::Part2DObject::H_Axis);
}
else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") {
int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str());
if (AxId >= 0 && AxId < sketch->getAxisCount()) {
hasValidAxis = true;
axis = sketch->getAxis(AxId);
}
}
if (hasValidAxis) {
axis *= SketchPlm;
Base::Vector3d base=axis.getBase();
Base::Vector3d dir=axis.getDirection();
Base.setValue(base.x,base.y,base.z);
Axis.setValue(dir.x,dir.y,dir.z);
}
}
}
}

View File

@ -62,6 +62,12 @@ public:
return "PartDesignGui::ViewProviderRevolution";
}
//@}
/// suggests a value for Reversed flag so that material is always added to the support
bool suggestReversed(void);
protected:
/// updates Axis from ReferenceAxis
void updateAxis(void);
};
} //namespace PartDesign

View File

@ -48,8 +48,8 @@
#include <Gui/FileDialog.h>
#include <Mod/Part/App/Part2DObject.h>
#include <Mod/PartDesign/App/FeatureAdditive.h>
#include <Mod/PartDesign/App/FeatureSubtractive.h>
#include <Mod/PartDesign/App/FeatureGroove.h>
#include <Mod/PartDesign/App/FeatureRevolution.h>
using namespace std;
@ -343,6 +343,9 @@ void CmdPartDesignRevolution::activated(int iMsg)
doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])",
FeatName.c_str(), sketch->getNameInDocument());
doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str());
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(getDocument()->getObject(FeatName.c_str()));
if (pcRevolution && pcRevolution->suggestReversed())
doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str());
updateActive();
if (isActiveObjectValid()) {
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument());
@ -413,6 +416,9 @@ void CmdPartDesignGroove::activated(int iMsg)
doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])",
FeatName.c_str(), sketch->getNameInDocument());
doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str());
PartDesign::Groove* pcGroove = static_cast<PartDesign::Groove*>(getDocument()->getObject(FeatName.c_str()));
if (pcGroove && pcGroove->suggestReversed())
doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str());
updateActive();
if (isActiveObjectValid()) {
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument());
@ -902,7 +908,6 @@ void CmdPartDesignMirrored::activated(int iMsg)
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());
@ -970,16 +975,15 @@ void CmdPartDesignLinearPattern::activated(int iMsg)
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Doc,str.str().c_str());
Part::Part2DObject *sketch = (static_cast<PartDesign::SketchBased*>(features.front()))->getVerifiedSketch();
Part::Part2DObject *sketch = (static_cast<PartDesign::SketchBased*>(features.front()))->getVerifiedSketch();
if (sketch)
doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])",
doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])",
FeatName.c_str(), sketch->getNameInDocument());
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());
@ -1047,16 +1051,15 @@ void CmdPartDesignPolarPattern::activated(int iMsg)
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Doc,str.str().c_str());
Part::Part2DObject *sketch = (static_cast<PartDesign::SketchBased*>(features.front()))->getVerifiedSketch();
Part::Part2DObject *sketch = (static_cast<PartDesign::SketchBased*>(features.front()))->getVerifiedSketch();
if (sketch)
doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])",
doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])",
FeatName.c_str(), sketch->getNameInDocument());
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());
@ -1129,7 +1132,6 @@ void CmdPartDesignScaled::activated(int iMsg)
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());
@ -1198,7 +1200,6 @@ void CmdPartDesignMultiTransform::activated(int iMsg)
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());

View File

@ -134,6 +134,9 @@ void TaskGrooveParameters::onAxisChanged(int num)
PartDesign::Groove* pcGroove = static_cast<PartDesign::Groove*>(GrooveView->getObject());
Sketcher::SketchObject *pcSketch = static_cast<Sketcher::SketchObject*>(pcGroove->Sketch.getValue());
if (pcSketch) {
App::DocumentObject *oldRefAxis = pcGroove->ReferenceAxis.getValue();
std::vector<std::string> oldSubRefAxis = pcGroove->ReferenceAxis.getSubValues();
int maxcount = pcSketch->getAxisCount()+2;
if (num == 0)
pcGroove->ReferenceAxis.setValue(pcSketch, std::vector<std::string>(1,"V_Axis"));
@ -146,6 +149,19 @@ void TaskGrooveParameters::onAxisChanged(int num)
}
if (num < maxcount && ui->axis->count() > maxcount)
ui->axis->setMaxCount(maxcount);
const std::vector<std::string> &newSubRefAxis = pcGroove->ReferenceAxis.getSubValues();
if (oldRefAxis != pcSketch ||
oldSubRefAxis.size() != newSubRefAxis.size() ||
oldSubRefAxis[0] != newSubRefAxis[0]) {
bool reversed = pcGroove->suggestReversed();
if (reversed != pcGroove->Reversed.getValue()) {
pcGroove->Reversed.setValue(reversed);
ui->checkBoxReversed->blockSignals(true);
ui->checkBoxReversed->setChecked(reversed);
ui->checkBoxReversed->blockSignals(false);
}
}
}
if (updateView())
pcGroove->getDocument()->recomputeFeature(pcGroove);

View File

@ -134,6 +134,9 @@ void TaskRevolutionParameters::onAxisChanged(int num)
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(RevolutionView->getObject());
Sketcher::SketchObject *pcSketch = static_cast<Sketcher::SketchObject*>(pcRevolution->Sketch.getValue());
if (pcSketch) {
App::DocumentObject *oldRefAxis = pcRevolution->ReferenceAxis.getValue();
std::vector<std::string> oldSubRefAxis = pcRevolution->ReferenceAxis.getSubValues();
int maxcount = pcSketch->getAxisCount()+2;
if (num == 0)
pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector<std::string>(1,"V_Axis"));
@ -146,6 +149,19 @@ void TaskRevolutionParameters::onAxisChanged(int num)
}
if (num < maxcount && ui->axis->count() > maxcount)
ui->axis->setMaxCount(maxcount);
const std::vector<std::string> &newSubRefAxis = pcRevolution->ReferenceAxis.getSubValues();
if (oldRefAxis != pcSketch ||
oldSubRefAxis.size() != newSubRefAxis.size() ||
oldSubRefAxis[0] != newSubRefAxis[0]) {
bool reversed = pcRevolution->suggestReversed();
if (reversed != pcRevolution->Reversed.getValue()) {
pcRevolution->Reversed.setValue(reversed);
ui->checkBoxReversed->blockSignals(true);
ui->checkBoxReversed->setChecked(reversed);
ui->checkBoxReversed->blockSignals(false);
}
}
}
if (updateView())
pcRevolution->getDocument()->recomputeFeature(pcRevolution);

View File

@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderLinearPattern,PartDesignGui::ViewProv
bool ViewProviderLinearPattern::setEdit(int ModNum)
{
ViewProviderTransformed::setEdit(ModNum);
if (ModNum == ViewProvider::Default ) {
TaskDlgLinearPatternParameters *linearpatternDlg = NULL;

View File

@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderMirrored,PartDesignGui::ViewProvider)
bool ViewProviderMirrored::setEdit(int ModNum)
{
ViewProviderTransformed::setEdit(ModNum);
if (ModNum == ViewProvider::Default ) {
TaskDlgMirroredParameters *mirroredDlg = NULL;

View File

@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderMultiTransform,PartDesignGui::ViewPro
bool ViewProviderMultiTransform::setEdit(int ModNum)
{
ViewProviderTransformed::setEdit(ModNum);
if (ModNum == ViewProvider::Default ) {
TaskDlgMultiTransformParameters *multitransformDlg = NULL;

View File

@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderPolarPattern,PartDesignGui::ViewProvi
bool ViewProviderPolarPattern::setEdit(int ModNum)
{
ViewProviderTransformed::setEdit(ModNum);
if (ModNum == ViewProvider::Default ) {
TaskDlgPolarPatternParameters *polarpatternDlg = NULL;

View File

@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderScaled,PartDesignGui::ViewProvider)
bool ViewProviderScaled::setEdit(int ModNum)
{
ViewProviderTransformed::setEdit(ModNum);
if (ModNum == ViewProvider::Default ) {
TaskDlgScaledParameters *scaledDlg = NULL;

View File

@ -24,15 +24,34 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Bnd_Box.hxx>
# include <BRep_Tool.hxx>
# include <BRepBndLib.hxx>
# include <BRepMesh_IncrementalMesh.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <Poly_Triangulation.hxx>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoIndexedFaceSet.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoMultipleCopy.h>
# include <Inventor/nodes/SoNormal.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoShapeHints.h>
# include <Inventor/nodes/SoTransparencyType.h>
#endif
#include "ViewProviderTransformed.h"
#include "TaskTransformedParameters.h"
#include <Mod/PartDesign/App/FeatureTransformed.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Base/Console.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/PartDesign/App/FeatureAdditive.h>
#include <Mod/PartDesign/App/FeatureSubtractive.h>
#include <Mod/PartDesign/App/FeatureTransformed.h>
using namespace PartDesignGui;
@ -46,6 +65,64 @@ void ViewProviderTransformed::setupContextMenu(QMenu* menu, QObject* receiver, c
PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member);
}
bool ViewProviderTransformed::setEdit(int ModNum)
{
pcRejectedRoot = new SoSeparator();
pcRejectedRoot->ref();
rejectedTrfms = new SoMultipleCopy();
rejectedTrfms->ref();
rejectedCoords = new SoCoordinate3();
rejectedCoords->ref();
rejectedNorms = new SoNormal();
rejectedNorms->ref();
rejectedFaceSet = new SoIndexedFaceSet();
rejectedFaceSet->ref();
SoPickStyle* rejectedPickStyle = new SoPickStyle();
rejectedPickStyle->style = SoPickStyle::UNPICKABLE;
SoShapeHints* rejectedHints = new SoShapeHints();
rejectedHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
rejectedHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
SoMaterialBinding* rejectedBind = new SoMaterialBinding();
SoTransparencyType* rejectedTransparencyType = new SoTransparencyType();
rejectedTransparencyType->value.setValue(SoGLRenderAction::BLEND);
SoMaterial* rejectedMaterial = new SoMaterial();
rejectedMaterial->diffuseColor.set1Value(0,SbColor(1.f,0.f,0.f));
rejectedMaterial->transparency.setValue(0.6f);
SoDrawStyle* rejectedFaceStyle = new SoDrawStyle();
rejectedFaceStyle->style = SoDrawStyle::FILLED;
SoNormalBinding* rejectedNormb = new SoNormalBinding();
rejectedNormb->value = SoNormalBinding::PER_VERTEX_INDEXED;
// just faces with no edges or points
pcRejectedRoot->addChild(rejectedPickStyle);
pcRejectedRoot->addChild(rejectedTransparencyType);
pcRejectedRoot->addChild(rejectedBind);
pcRejectedRoot->addChild(rejectedMaterial);
pcRejectedRoot->addChild(rejectedHints);
pcRejectedRoot->addChild(rejectedFaceStyle);
pcRejectedRoot->addChild(rejectedCoords);
pcRejectedRoot->addChild(rejectedNorms);
pcRejectedRoot->addChild(rejectedNormb);
pcRejectedRoot->addChild(rejectedTrfms);
rejectedTrfms->addChild(rejectedFaceSet);
pcRoot->addChild(pcRejectedRoot);
recomputeFeature();
return true;
}
void ViewProviderTransformed::unsetEdit(int ModNum)
{
if (ModNum == ViewProvider::Default) {
@ -55,6 +132,17 @@ void ViewProviderTransformed::unsetEdit(int ModNum)
else {
PartGui::ViewProviderPart::unsetEdit(ModNum);
}
rejectedTrfms->removeAllChildren();
pcRejectedRoot->removeAllChildren();
pcRoot->removeChild(pcRejectedRoot);
pcRejectedRoot->unref();
rejectedTrfms->unref();
rejectedCoords->unref();
rejectedNorms->unref();
rejectedFaceSet->unref();
}
bool ViewProviderTransformed::onDelete(const std::vector<std::string> &)
@ -126,5 +214,174 @@ void ViewProviderTransformed::recomputeFeature(void)
msg = msg.arg(QObject::tr("Transformation succeeded"));
}
signalDiagnosis(msg);
TopoDS_Shape shape;
if (rejected != 0) {
// FIXME: create a compound if there are more than one originals
App::DocumentObject* original = pcTransformed->Originals.getValues().front();
if (original->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) {
PartDesign::Additive* addFeature = static_cast<PartDesign::Additive*>(original);
shape = addFeature->AddShape.getShape()._Shape;
} else if (original->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(original);
shape = subFeature->SubShape.getShape()._Shape;
}
}
if (rejected == 0 || shape.IsNull()) {
rejectedCoords ->point .setNum(0);
rejectedNorms ->vector .setNum(0);
rejectedFaceSet ->coordIndex .setNum(0);
rejectedTrfms ->matrix .setNum(0);
} else {
// Display the rejected transformations in red
TopoDS_Shape cShape(shape);
try {
// calculating the deflection value
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
{
Bnd_Box bounds;
BRepBndLib::Add(cShape, bounds);
bounds.SetGap(0.0);
bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
}
Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue();
// create or use the mesh on the data structure
BRepMesh_IncrementalMesh myMesh(cShape,deflection);
// We must reset the location here because the transformation data
// are set in the placement property
TopLoc_Location aLoc;
cShape.Location(aLoc);
// count triangles and nodes in the mesh
int nbrTriangles=0, nbrNodes=0;
TopExp_Explorer Ex;
for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) {
Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc);
// Note: we must also count empty faces
if (!mesh.IsNull()) {
nbrTriangles += mesh->NbTriangles();
nbrNodes += mesh->NbNodes();
}
}
// create memory for the nodes and indexes
rejectedCoords ->point .setNum(nbrNodes);
rejectedNorms ->vector .setNum(nbrNodes);
rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4);
// get the raw memory for fast fill up
SbVec3f* verts = rejectedCoords ->point .startEditing();
SbVec3f* norms = rejectedNorms ->vector .startEditing();
int32_t* index = rejectedFaceSet ->coordIndex .startEditing();
// preset the normal vector with null vector
for (int i=0; i < nbrNodes; i++)
norms[i]= SbVec3f(0.0,0.0,0.0);
int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0;
for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) {
TopLoc_Location aLoc;
const TopoDS_Face &actFace = TopoDS::Face(Ex.Current());
// get the mesh of the shape
Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc);
if (mesh.IsNull()) continue;
// getting the transformation of the shape/face
gp_Trsf myTransf;
Standard_Boolean identity = true;
if (!aLoc.IsIdentity()) {
identity = false;
myTransf = aLoc.Transformation();
}
// getting size of node and triangle array of this face
int nbNodesInFace = mesh->NbNodes();
int nbTriInFace = mesh->NbTriangles();
// check orientation
TopAbs_Orientation orient = actFace.Orientation();
// cycling through the poly mesh
const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
for (int g=1; g <= nbTriInFace; g++) {
// Get the triangle
Standard_Integer N1,N2,N3;
Triangles(g).Get(N1,N2,N3);
// change orientation of the triangle if the face is reversed
if ( orient != TopAbs_FORWARD ) {
Standard_Integer tmp = N1;
N1 = N2;
N2 = tmp;
}
// get the 3 points of this triangle
gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3));
// transform the vertices to the place of the face
if (!identity) {
V1.Transform(myTransf);
V2.Transform(myTransf);
V3.Transform(myTransf);
}
// calculating per vertex normals
// Calculate triangle normal
gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
gp_Vec Normal = (v2-v1)^(v3-v1);
// add the triangle normal to the vertex normal for all points of this triangle
norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
// set the vertices
verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z()));
verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z()));
verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z()));
// set the index vector with the 3 point indexes and the end delimiter
index[FaceTriaOffset*4+4*(g-1)] = FaceNodeOffset+N1-1;
index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1;
index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1;
index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX;
}
// counting up the per Face offsets
FaceNodeOffset += nbNodesInFace;
FaceTriaOffset += nbTriInFace;
}
// normalize all normals
for (int i=0; i < nbrNodes; i++)
norms[i].normalize();
// end the editing of the nodes
rejectedCoords ->point .finishEditing();
rejectedNorms ->vector .finishEditing();
rejectedFaceSet ->coordIndex .finishEditing();
// fill in the transformation matrices
rejectedTrfms->matrix.setNum(rejected);
SbMatrix* mats = rejectedTrfms->matrix.startEditing();
std::list<gp_Trsf> rejected_trsf = pcTransformed->getRejectedTransformations();
std::list<gp_Trsf>::const_iterator trsf = rejected_trsf.begin();
for (int i=0; i < rejected; i++,trsf++) {
Base::Matrix4D mat;
Part::TopoShape::convertToMatrix(*trsf,mat);
mats[i] = convert(mat);
}
rejectedTrfms->matrix.finishEditing();
}
catch (...) {
Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n",
pcTransformed->getNameInDocument());
}
}
}

View File

@ -26,6 +26,12 @@
#include "ViewProvider.h"
class SoCoordinate3;
class SoIndexedFaceSet;
class SoMultipleCopy;
class SoNormal;
class SoSeparator;
namespace PartDesignGui {
class TaskDlgTransformedParameters;
@ -53,10 +59,18 @@ public:
std::string featureName;
protected:
virtual bool setEdit(int ModNum) { return false; }
virtual bool setEdit(int ModNum);
virtual void unsetEdit(int ModNum);
const bool checkDlgOpen(TaskDlgTransformedParameters* transformedDlg);
// nodes for the representation of rejected repetitions
SoGroup * pcRejectedRoot;
SoMultipleCopy * rejectedTrfms;
SoCoordinate3 * rejectedCoords;
SoNormal * rejectedNorms;
SoIndexedFaceSet * rejectedFaceSet;
public:
void recomputeFeature();
};