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 += "]" result += "]"
return 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): def addComponents(objectsList,host):
'''addComponents(objectsList,hostObject): adds the given object or the objects '''addComponents(objectsList,hostObject): adds the given object or the objects
from the given list as components to the given host Object. Use this for from the given list as components to the given host Object. Use this for
@ -309,42 +325,59 @@ def getCutVolume(cutplane,shapes):
invcutvolume = cutface.extrude(cutnormal) invcutvolume = cutface.extrude(cutnormal)
return cutface,cutvolume,invcutvolume 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): def meshToShape(obj,mark=True):
'''meshToShape(object,[mark]): turns a mesh into a shape, joining coplanar facets. If '''meshToShape(object,[mark]): turns a mesh into a shape, joining coplanar facets. If
mark is True (default), non-solid objects will be marked in red''' mark is True (default), non-solid objects will be marked in red'''
name = obj.Name name = obj.Name
import Part, MeshPart, DraftGeomUtils
if "Mesh" in obj.PropertiesList: if "Mesh" in obj.PropertiesList:
faces = [] faces = []
mesh = obj.Mesh mesh = obj.Mesh
plac = obj.Placement plac = obj.Placement
segments = mesh.getPlanarSegments(0.001) # use rather strict tolerance here solid = getShapeFromMesh(mesh)
print len(segments)," segments ",segments if solid:
for i in segments: if solid.isClosed() and solid.isValid():
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():
FreeCAD.ActiveDocument.removeObject(name) FreeCAD.ActiveDocument.removeObject(name)
newobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name) newobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
newobj.Shape = solid newobj.Shape = solid
newobj.Placement = plac newobj.Placement = plac
if not solid.isClosed(): if (not solid.isClosed()) or (not solid.isValid()):
if mark: if mark:
newobj.ViewObject.ShapeColor = (1.0,0.0,0.0,1.0) newobj.ViewObject.ShapeColor = (1.0,0.0,0.0,1.0)
return newobj 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.Width = width
obj.Height = height obj.Height = height
obj.Length = length obj.Length = length
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Structure")
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)
return obj return obj
def makeStructuralSystem(objects,axes): def makeStructuralSystem(objects,axes):
@ -172,6 +167,12 @@ class _Structure(ArchComponent.Component):
if base.Wires[0].isClosed(): if base.Wires[0].isClosed():
base = Part.Face(base.Wires[0]) 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: else:
if obj.Normal == Vector(0,0,0): if obj.Normal == Vector(0,0,0):
normal = Vector(0,0,1) 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 FreeCAD import Vector
from PyQt4 import QtCore from PyQt4 import QtCore
from DraftTools import translate 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) obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name)
_Wall(obj) _Wall(obj)
_ViewProviderWall(obj.ViewObject) _ViewProviderWall(obj.ViewObject)
if baseobj: obj.Base = baseobj if baseobj:
if width: obj.Width = width obj.Base = baseobj
if height: obj.Height = height if width:
obj.Width = width
if height:
obj.Height = height
obj.Align = align obj.Align = align
if obj.Base: obj.Base.ViewObject.hide() if obj.Base:
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") obj.Base.ViewObject.hide()
c = p.GetUnsigned("WallColor") obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Wall")
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)
return obj return obj
def joinWalls(walls): def joinWalls(walls):
@ -357,7 +356,7 @@ class _Wall(ArchComponent.Component):
# computing shape # computing shape
base = None base = None
if obj.Base.isDerivedFrom("Part::Feature"): 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() base = obj.Base.Shape.copy()
if base.Solids: if base.Solids:
pass pass
@ -380,7 +379,17 @@ class _Wall(ArchComponent.Component):
if sh: if sh:
base = sh base = sh
else: else:
base = None
FreeCAD.Console.PrintError(str(translate("Arch","Error: Invalid base object"))) 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: if base:
for app in obj.Additions: 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 FreeCAD import Vector
from PyQt4 import QtCore,QtGui from PyQt4 import QtCore,QtGui
from DraftTools import translate from DraftTools import translate
@ -49,12 +49,7 @@ def makeWindow(baseobj=None,width=None,name=str(translate("Arch","Window"))):
if obj.Base: if obj.Base:
obj.Base.ViewObject.DisplayMode = "Wireframe" obj.Base.ViewObject.DisplayMode = "Wireframe"
obj.Base.ViewObject.hide() obj.Base.ViewObject.hide()
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Window")
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)
return obj return obj
def makeDefaultWindowPart(obj): def makeDefaultWindowPart(obj):