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()
Exemple #3
0
    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)
Exemple #4
0
 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)