Arch: Better auto-fuse for walls
This commit is contained in:
parent
24f559be9a
commit
913aa919dd
|
@ -318,8 +318,15 @@ class Component:
|
|||
if base:
|
||||
if base.isNull():
|
||||
base = None
|
||||
|
||||
if (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window")):
|
||||
|
||||
# special case, both walls with coinciding endpoints
|
||||
import ArchWall
|
||||
js = ArchWall.mergeShapes(o,obj)
|
||||
if js:
|
||||
add = js.cut(base)
|
||||
base = base.fuse(add)
|
||||
|
||||
elif (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window")):
|
||||
if base:
|
||||
# windows can be additions or subtractions, treated the same way
|
||||
if hasattr(self,"Width"):
|
||||
|
|
|
@ -74,9 +74,33 @@ def joinWalls(walls):
|
|||
sk.addGeometry(e)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return base
|
||||
|
||||
def mergeShapes(w1,w2):
|
||||
"returns a Shape built on two walls that share same properties and have a coincident endpoint"
|
||||
if not areSameWallTypes([w1,w2]):
|
||||
return None
|
||||
if (not hasattr(w1.Base,"Shape")) or (not hasattr(w2.Base,"Shape")):
|
||||
return None
|
||||
if w1.Base.Shape.Faces or w2.Base.Shape.Faces:
|
||||
return None
|
||||
|
||||
eds = w1.Base.Shape.Edges + w2.Base.Shape.Edges
|
||||
import DraftGeomUtils
|
||||
w = DraftGeomUtils.findWires(eds)
|
||||
if len(w) == 1:
|
||||
print "found common wire"
|
||||
normal,width,height = w1.Proxy.getDefaultValues(w1)
|
||||
print w[0].Edges
|
||||
sh = w1.Proxy.getBase(w1,w[0],normal,width,height)
|
||||
print sh
|
||||
return sh
|
||||
return None
|
||||
|
||||
def areSameWallTypes(walls):
|
||||
"returns True is all the walls in the given list have same height, width, and alignment"
|
||||
for w in walls:
|
||||
if Draft.getType(w) != "Wall":
|
||||
return False
|
||||
for att in ["Width","Height","Align"]:
|
||||
value = None
|
||||
for w in walls:
|
||||
|
@ -276,6 +300,64 @@ class _Wall(ArchComponent.Component):
|
|||
self.hideSubobjects(obj,prop)
|
||||
if prop in ["Base","Height","Width","Align","Additions","Subtractions"]:
|
||||
self.createGeometry(obj)
|
||||
|
||||
def getDefaultValues(self,obj):
|
||||
"returns normal,width,height values from this wall"
|
||||
width = 1.0
|
||||
if hasattr(obj,"Width"):
|
||||
if obj.Width:
|
||||
width = obj.Width
|
||||
height = normal = None
|
||||
if hasattr(obj,"Height"):
|
||||
if obj.Height:
|
||||
height = obj.Height
|
||||
else:
|
||||
for p in obj.InList:
|
||||
if Draft.getType(p) == "Floor":
|
||||
height = p.Height
|
||||
if not height:
|
||||
height = 1.0
|
||||
if hasattr(obj,"Normal"):
|
||||
if obj.Normal == Vector(0,0,0):
|
||||
normal = Vector(0,0,1)
|
||||
else:
|
||||
normal = Vector(obj.Normal)
|
||||
else:
|
||||
normal = Vector(0,0,1)
|
||||
return normal,width,height
|
||||
|
||||
def getBase(self,obj,wire,normal,width,height):
|
||||
"returns a full shape from a base wire"
|
||||
import DraftGeomUtils,Part
|
||||
flat = False
|
||||
if hasattr(obj.ViewObject,"DisplayMode"):
|
||||
flat = (obj.ViewObject.DisplayMode == "Flat 2D")
|
||||
dvec = DraftGeomUtils.vec(wire.Edges[0]).cross(normal)
|
||||
if not DraftVecUtils.isNull(dvec):
|
||||
dvec.normalize()
|
||||
if obj.Align == "Left":
|
||||
dvec = dvec.multiply(width)
|
||||
w2 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
|
||||
sh = DraftGeomUtils.bind(w1,w2)
|
||||
elif obj.Align == "Right":
|
||||
dvec = dvec.multiply(width)
|
||||
dvec = DraftVecUtils.neg(dvec)
|
||||
w2 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
|
||||
sh = DraftGeomUtils.bind(w1,w2)
|
||||
elif obj.Align == "Center":
|
||||
dvec = dvec.multiply(width/2)
|
||||
w1 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
dvec = DraftVecUtils.neg(dvec)
|
||||
w2 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
sh = DraftGeomUtils.bind(w1,w2)
|
||||
# fixing self-intersections
|
||||
sh.fix(0.1,0,1)
|
||||
if height and (not flat):
|
||||
norm = Vector(normal).multiply(height)
|
||||
sh = sh.extrude(norm)
|
||||
return sh
|
||||
|
||||
def createGeometry(self,obj):
|
||||
"builds the wall shape"
|
||||
|
@ -284,59 +366,9 @@ class _Wall(ArchComponent.Component):
|
|||
return
|
||||
|
||||
import Part, DraftGeomUtils
|
||||
|
||||
flat = False
|
||||
if hasattr(obj.ViewObject,"DisplayMode"):
|
||||
flat = (obj.ViewObject.DisplayMode == "Flat 2D")
|
||||
|
||||
width = 1.0
|
||||
if hasattr(obj,"Width"):
|
||||
if obj.Width:
|
||||
width = obj.Width
|
||||
|
||||
def getbase(wire):
|
||||
"returns a full shape from a base wire"
|
||||
dvec = DraftGeomUtils.vec(wire.Edges[0]).cross(normal)
|
||||
dvec.normalize()
|
||||
if obj.Align == "Left":
|
||||
dvec = dvec.multiply(width)
|
||||
w2 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
|
||||
sh = DraftGeomUtils.bind(w1,w2)
|
||||
elif obj.Align == "Right":
|
||||
dvec = dvec.multiply(width)
|
||||
dvec = DraftVecUtils.neg(dvec)
|
||||
w2 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
|
||||
sh = DraftGeomUtils.bind(w1,w2)
|
||||
elif obj.Align == "Center":
|
||||
dvec = dvec.multiply(width/2)
|
||||
w1 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
dvec = DraftVecUtils.neg(dvec)
|
||||
w2 = DraftGeomUtils.offsetWire(wire,dvec)
|
||||
sh = DraftGeomUtils.bind(w1,w2)
|
||||
# fixing self-intersections
|
||||
sh.fix(0.1,0,1)
|
||||
if height and (not flat):
|
||||
norm = Vector(normal).multiply(height)
|
||||
sh = sh.extrude(norm)
|
||||
return sh
|
||||
|
||||
pl = obj.Placement
|
||||
|
||||
# getting default values
|
||||
height = normal = None
|
||||
if obj.Height:
|
||||
height = obj.Height
|
||||
else:
|
||||
for p in obj.InList:
|
||||
if Draft.getType(p) == "Floor":
|
||||
height = p.Height
|
||||
if not height: height = 1
|
||||
if obj.Normal == Vector(0,0,0):
|
||||
normal = Vector(0,0,1)
|
||||
else:
|
||||
normal = Vector(obj.Normal)
|
||||
normal,width,height = self.getDefaultValues(obj)
|
||||
|
||||
# computing shape
|
||||
base = None
|
||||
|
@ -353,7 +385,7 @@ class _Wall(ArchComponent.Component):
|
|||
elif len(base.Wires) == 1:
|
||||
temp = None
|
||||
for wire in obj.Base.Shape.Wires:
|
||||
sh = getbase(wire)
|
||||
sh = self.getBase(obj,wire,normal,width,height)
|
||||
if temp:
|
||||
temp = temp.fuse(sh)
|
||||
else:
|
||||
|
@ -362,7 +394,7 @@ class _Wall(ArchComponent.Component):
|
|||
elif base.Edges:
|
||||
wire = Part.Wire(base.Edges)
|
||||
if wire:
|
||||
sh = getbase(wire)
|
||||
sh = self.getBase(obj,wire,normal,width,height)
|
||||
if sh:
|
||||
base = sh
|
||||
else:
|
||||
|
|
|
@ -205,8 +205,10 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
return [pt2]
|
||||
norm1 = pt2.sub(pt1).cross(pt3.sub(pt1))
|
||||
norm2 = pt2.sub(pt4).cross(pt3.sub(pt4))
|
||||
norm1.normalize()
|
||||
norm2.normalize()
|
||||
if not DraftVecUtils.isNull(norm1):
|
||||
norm1.normalize()
|
||||
if not DraftVecUtils.isNull(norm2):
|
||||
norm2.normalize()
|
||||
if DraftVecUtils.isNull(norm1.cross(norm2)):
|
||||
vec1 = pt2.sub(pt1)
|
||||
vec2 = pt4.sub(pt3)
|
||||
|
|
Loading…
Reference in New Issue
Block a user