def create(self, obj, wall, o1, o2): self.obj = obj self.o1 = o1 self.o2 = o2 self.lookup() left = o1["l"] # set the initial locaton of the object at the middle of the wall segment sign = 1. if left else -1. obj.location = (o1.location + o2.location + sign*self.width.location.x*(o2.location-o1.location).normalized())/2. obj.location.z = self.floorToWindow # set drivers for EMPTYs controlling interior and exterior parts of the window # the interior part i = self.int.driver_add("location", 1) addSinglePropVariable(i, "w", o2, "[\"w\"]") i.driver.expression = "-w/2." # the exterior part e = self.ext.driver_add("location", 1) addSinglePropVariable(e, "w", o2, "[\"w\"]") e.driver.expression = "w/2." addBooleanModifier(wall.mesh, o2["g"], self.envelope) rz = obj.driver_add("rotation_euler", 2) addTransformsVariable(rz, "x1", o2 if left else o1, "LOC_X") addTransformsVariable(rz, "x2", o1 if left else o2, "LOC_X") addTransformsVariable(rz, "y1", o2 if left else o1, "LOC_Y") addTransformsVariable(rz, "y2", o1 if left else o2, "LOC_Y") rz.driver.expression = "atan2(y2-y1,x2-x1)" self.keepRatioCenter()
def create(self, obj, wall, o1, o2): self.obj = obj self.o1 = o1 self.o2 = o2 self.lookup() left = o1["l"] # set the initial locaton of the object at the middle of the wall segment sign = 1. if left else -1. obj.location = (o1.location + o2.location + sign * self.width.location.x * (o2.location - o1.location).normalized()) / 2. obj.location.z = self.floorToWindow # set drivers for EMPTYs controlling interior and exterior parts of the window # the interior part i = self.int.driver_add("location", 1) addSinglePropVariable(i, "w", o2, "[\"w\"]") i.driver.expression = "-w/2." # the exterior part e = self.ext.driver_add("location", 1) addSinglePropVariable(e, "w", o2, "[\"w\"]") e.driver.expression = "w/2." addBooleanModifier(wall.mesh, o2["g"], self.envelope) rz = obj.driver_add("rotation_euler", 2) addTransformsVariable(rz, "x1", o2 if left else o1, "LOC_X") addTransformsVariable(rz, "x2", o1 if left else o2, "LOC_X") addTransformsVariable(rz, "y1", o2 if left else o1, "LOC_Y") addTransformsVariable(rz, "y2", o1 if left else o2, "LOC_Y") rz.driver.expression = "atan2(y2-y1,x2-x1)" self.keepRatioCenter()
def treatInsertions(self, controls): """ The function treats insertions (e.g. windows, doors) relevant for the finish. Namely, a BOOLEAN modifier is created for each relevant opening. """ from item.opening import getReferencesForOpening # build a list of EMPTYs that defines each wall part that forms the finish walls = {} _c = controls[-1] for c in controls: # consider the wall part defined by <_c> and <c> if _c["t"] == "wc": if c["t"] == "wc": # both <_c> and <c> are corner EMPTYs o1 = _c o2 = c else: # <c> is attached # choose <o> depending on if <_c> and <c> belong to the same wall part if _c["m"] == c["m"]: o1 = _c o2 = c else: o1, o2 = getReferencesForAttached(c) elif c["t"] == "wc": # <_c> is attached # choose <o1> depending on if <_c> and <c> belong to the same wall part if _c["m"] == c["m"]: o1 = _c o2 = c else: o1, o2 = getReferencesForAttached(_c) else: # both <_c> and <c> are attached EMPTYs _m_self = _c["m"] _m_base = getReferencesForAttached(_c)[0]["m"] m_self = c["m"] m_base = getReferencesForAttached(c)[0]["m"] if _m_self == m_self and (("p" in c and c["p"] == _c["g"]) or ("n" in c and c["n"] == _c["g"])): o1 = _c o2 = c elif _m_base == m_base: o1, o2 = getReferencesForAttached(c) elif _m_base == m_self: o1, o2 = getReferencesForAttached(_c) else: # _m_self == m_base o1, o2 = getReferencesForAttached(c) # ensure that <o2> follows <o1> if "n" in o2 and o2["n"] == o1["g"]: o1, o2 = o2, o1 # <o2> defines the wall part where the finish part defined by <_c> and <c> is placed # create an entry for <o2> walls[o2["g"]] = [o1, o2, _c, c] _c = c # iterate through immediate children of the parent Blender object of the finish for o in self.obj.parent.children: if "t" in o and (o["t"] == "window" or o["t"] == "door"): o1, o2 = getReferencesForOpening(o) # ensure that <o2> follows <o1> if "n" in o2 and o2["n"] == o1["g"]: o2 = o1 # <o2> defines the wall part where the opening <o> is placed # check if the finish also uses the wall part defined by <o2> if o2["g"] in walls: # if necessary, calculate the position of the finish part along the wall part defined by <o2> # lazy calculation is used! e = walls[o2["g"]] if not isinstance(e[2], float): l1 = (e[2].location - e[0].location).length l2 = (e[3].location - e[0].location).length if l1 > l2: l1, l2 = l2, l1 e[2] = l1 e[3] = l2 # get an instance of <Opening> class item = getItem(self.context, self.op, o) # calculate the position of the origin of the opening along the wall part defined by <o2> l1 = (e[1].location - e[0].location).dot(o.location - e[0].location) / ( e[1].location - e[0].location).length addModifier = True # check if l1 is inside the finish part if not e[2] < l1 < e[3]: # calculate the position of the other end of the opening along the wall part defined by <o2> # the width of the opening: l2 = item.width.location.x l2 = (l1 - l2) if o1["l"] else (l1 + l2) if not e[2] < l2 < e[3]: addModifier = False if addModifier: addBooleanModifier(self.obj, o.name, item.envelope)
def treatInsertions(self, controls): """ The function treats insertions (e.g. windows, doors) relevant for the finish. Namely, a BOOLEAN modifier is created for each relevant opening. """ from item.opening import getReferencesForOpening # build a list of EMPTYs that defines each wall part that forms the finish walls = {} _c = controls[-1] for c in controls: # consider the wall part defined by <_c> and <c> if _c["t"] == "wc": if c["t"] == "wc": # both <_c> and <c> are corner EMPTYs o1 = _c o2 = c else: # <c> is attached # choose <o> depending on if <_c> and <c> belong to the same wall part if _c["m"] == c["m"]: o1 = _c o2 = c else: o1, o2 = getReferencesForAttached(c) elif c["t"] == "wc": # <_c> is attached # choose <o1> depending on if <_c> and <c> belong to the same wall part if _c["m"] == c["m"]: o1 = _c o2 = c else: o1, o2 = getReferencesForAttached(_c) else: # both <_c> and <c> are attached EMPTYs _m_self = _c["m"] _m_base = getReferencesForAttached(_c)[0]["m"] m_self = c["m"] m_base = getReferencesForAttached(c)[0]["m"] if _m_self == m_self and (("p" in c and c["p"] == _c["g"]) or ("n" in c and c["n"] == _c["g"])): o1 = _c o2 = c elif _m_base == m_base: o1, o2 = getReferencesForAttached(c) elif _m_base == m_self: o1, o2 = getReferencesForAttached(_c) else: # _m_self == m_base o1, o2 = getReferencesForAttached(c) # ensure that <o2> follows <o1> if "n" in o2 and o2["n"] == o1["g"]: o1, o2 = o2, o1 # <o2> defines the wall part where the finish part defined by <_c> and <c> is placed # create an entry for <o2> walls[o2["g"]] = [o1, o2, _c, c] _c = c # iterate through immediate children of the parent Blender object of the finish for o in self.obj.parent.children: if "t" in o and (o["t"] == "window" or o["t"] == "door"): o1, o2 = getReferencesForOpening(o) # ensure that <o2> follows <o1> if "n" in o2 and o2["n"] == o1["g"]: o2 = o1 # <o2> defines the wall part where the opening <o> is placed # check if the finish also uses the wall part defined by <o2> if o2["g"] in walls: # if necessary, calculate the position of the finish part along the wall part defined by <o2> # lazy calculation is used! e = walls[o2["g"]] if not isinstance(e[2], float): l1 = (e[2].location - e[0].location).length l2 = (e[3].location - e[0].location).length if l1 > l2: l1, l2 = l2, l1 e[2] = l1 e[3] = l2 # get an instance of <Opening> class item = getItem(self.context, self.op, o) # calculate the position of the origin of the opening along the wall part defined by <o2> l1 = (e[1].location - e[0].location).dot(o.location - e[0].location) / (e[1].location - e[0].location).length addModifier = True # check if l1 is inside the finish part if not e[2] < l1 <e [3]: # calculate the position of the other end of the opening along the wall part defined by <o2> # the width of the opening: l2 = item.width.location.x l2 = (l1 - l2) if o1["l"] else (l1 + l2) if not e[2] < l2 <e [3]: addModifier = False if addModifier: addBooleanModifier(self.obj, o.name, item.envelope)