Arch: Walls and Structs can now be created directly from meshes

This commit is contained in:
Yorik van Havre 2012-08-05 19:03:27 -03:00
parent aae9b17e32
commit 43b7b9834d
4 changed files with 86 additions and 48 deletions

View File

@ -43,6 +43,22 @@ def getStringList(objects):
result += "]"
return result
def getDefaultColor(objectType):
'''getDefaultColor(string): returns a color value for the given object
type (Wall, Structure, Window)'''
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
if objectType == "Wall":
c = p.GetUnsigned("WallColor")
elif objectType == "Structure":
c = p.GetUnsigned("StructureColor")
else:
c = p.GetUnsigned("WindowsColor")
r = float((c>>24)&0xFF)/255.0
g = float((c>>16)&0xFF)/255.0
b = float((c>>8)&0xFF)/255.0
result = (r,g,b,1.0)
return result
def addComponents(objectsList,host):
'''addComponents(objectsList,hostObject): adds the given object or the objects
from the given list as components to the given host Object. Use this for
@ -308,6 +324,41 @@ def getCutVolume(cutplane,shapes):
cutnormal = DraftVecUtils.neg(cutnormal)
invcutvolume = cutface.extrude(cutnormal)
return cutface,cutvolume,invcutvolume
def getShapeFromMesh(mesh):
import Part, MeshPart
if mesh.isSolid() and (mesh.countComponents() == 1):
# use the best method
faces = []
for f in mesh.Facets:
p=f.Points+[f.Points[0]]
pts = []
for pp in p:
pts.append(FreeCAD.Vector(pp[0],pp[1],pp[2]))
faces.append(Part.Face(Part.makePolygon(pts)))
shell = Part.makeShell(faces)
solid = Part.Solid(shell)
solid = solid.removeSplitter()
return solid
faces = []
segments = mesh.getPlanarSegments(0.001) # use rather strict tolerance here
for i in segments:
if len(i) > 0:
wires = MeshPart.wireFromSegment(mesh, i)
if wires:
faces.append(makeFace(wires))
try:
se = Part.makeShell(faces)
except:
return None
else:
try:
solid = Part.Solid(se)
except:
return se
else:
return solid
def meshToShape(obj,mark=True):
@ -315,36 +366,18 @@ def meshToShape(obj,mark=True):
mark is True (default), non-solid objects will be marked in red'''
name = obj.Name
import Part, MeshPart, DraftGeomUtils
if "Mesh" in obj.PropertiesList:
faces = []
mesh = obj.Mesh
plac = obj.Placement
segments = mesh.getPlanarSegments(0.001) # use rather strict tolerance here
print len(segments)," segments ",segments
for i in segments:
print "treating",segments.index(i),i
if len(i) > 0:
wires = MeshPart.wireFromSegment(mesh, i)
print "wire done"
print wires
if wires:
faces.append(makeFace(wires))
print "done facing"
print "faces",faces
try:
se = Part.makeShell(faces)
solid = Part.Solid(se)
except:
raise
else:
if solid.isClosed():
solid = getShapeFromMesh(mesh)
if solid:
if solid.isClosed() and solid.isValid():
FreeCAD.ActiveDocument.removeObject(name)
newobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
newobj.Shape = solid
newobj.Placement = plac
if not solid.isClosed():
if (not solid.isClosed()) or (not solid.isValid()):
if mark:
newobj.ViewObject.ShapeColor = (1.0,0.0,0.0,1.0)
return newobj

View File

@ -44,12 +44,7 @@ def makeStructure(baseobj=None,length=1,width=1,height=1,name=str(translate("Arc
obj.Width = width
obj.Height = height
obj.Length = length
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
c = p.GetUnsigned("StructureColor")
r = float((c>>24)&0xFF)/255.0
g = float((c>>16)&0xFF)/255.0
b = float((c>>8)&0xFF)/255.0
obj.ViewObject.ShapeColor = (r,g,b,1.0)
obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Structure")
return obj
def makeStructuralSystem(objects,axes):
@ -171,7 +166,13 @@ class _Structure(ArchComponent.Component):
elif (len(base.Wires) == 1):
if base.Wires[0].isClosed():
base = Part.Face(base.Wires[0])
base = base.extrude(normal)
base = base.extrude(normal)
elif obj.Base.isDerivedFrom("Mesh::Feature"):
if obj.Mesh.isSolid():
if obj.Mesh.countComponents() == 1:
sh = ArchCommands.getShapeFromMesh(obj.Mesh)
if sh.isClosed() and sh.isValid() and sh.Solids:
base = sh
else:
if obj.Normal == Vector(0,0,0):
normal = Vector(0,0,1)

View File

@ -21,7 +21,7 @@
#* *
#***************************************************************************
import FreeCAD,FreeCADGui,Draft,ArchComponent,DraftVecUtils
import FreeCAD,FreeCADGui,Draft,ArchComponent,DraftVecUtils,ArchCommands
from FreeCAD import Vector
from PyQt4 import QtCore
from DraftTools import translate
@ -37,17 +37,16 @@ def makeWall(baseobj=None,width=None,height=None,align="Center",name=str(transla
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name)
_Wall(obj)
_ViewProviderWall(obj.ViewObject)
if baseobj: obj.Base = baseobj
if width: obj.Width = width
if height: obj.Height = height
if baseobj:
obj.Base = baseobj
if width:
obj.Width = width
if height:
obj.Height = height
obj.Align = align
if obj.Base: obj.Base.ViewObject.hide()
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
c = p.GetUnsigned("WallColor")
r = float((c>>24)&0xFF)/255.0
g = float((c>>16)&0xFF)/255.0
b = float((c>>8)&0xFF)/255.0
obj.ViewObject.ShapeColor = (r,g,b,1.0)
if obj.Base:
obj.Base.ViewObject.hide()
obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Wall")
return obj
def joinWalls(walls):
@ -357,7 +356,7 @@ class _Wall(ArchComponent.Component):
# computing shape
base = None
if obj.Base.isDerivedFrom("Part::Feature"):
if not obj.Base.Shape.isNull():
if obj.Base.isValid() and (not obj.Base.Shape.isNull()):
base = obj.Base.Shape.copy()
if base.Solids:
pass
@ -380,7 +379,17 @@ class _Wall(ArchComponent.Component):
if sh:
base = sh
else:
base = None
FreeCAD.Console.PrintError(str(translate("Arch","Error: Invalid base object")))
elif obj.Base.isDerivedFrom("Mesh::Feature"):
if obj.Base.Mesh.isSolid():
if obj.Base.Mesh.countComponents() == 1:
sh = ArchCommands.getShapeFromMesh(obj.Base.Mesh)
if sh.isClosed() and sh.isValid() and sh.Solids and (not sh.isNull()):
base = sh
else:
FreeCAD.Console.PrintWarning("This mesh is an invalid solid")
obj.Base.ViewObject.show()
if base:
for app in obj.Additions:

View File

@ -21,7 +21,7 @@
#* *
#***************************************************************************
import FreeCAD,FreeCADGui,Draft,ArchComponent,DraftVecUtils
import FreeCAD,FreeCADGui,Draft,ArchComponent,DraftVecUtils,ArchCommands
from FreeCAD import Vector
from PyQt4 import QtCore,QtGui
from DraftTools import translate
@ -49,12 +49,7 @@ def makeWindow(baseobj=None,width=None,name=str(translate("Arch","Window"))):
if obj.Base:
obj.Base.ViewObject.DisplayMode = "Wireframe"
obj.Base.ViewObject.hide()
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
c = p.GetUnsigned("WindowColor")
r = float((c>>24)&0xFF)/255.0
g = float((c>>16)&0xFF)/255.0
b = float((c>>8)&0xFF)/255.0
obj.ViewObject.ShapeColor = (r,g,b,1.0)
obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Window")
return obj
def makeDefaultWindowPart(obj):