Custom Door Object

A forum dedicated to the Draft, Arch and BIM workbenches development.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Custom Door Object

Post by chakkree »

Parametric Door Object.(Fixed Type,slided), can change value of width,height.
But I can not set transparent to a glass panel.

Code: Select all

"""
   Custom Door Object
"""

import ArchCommands,ArchComponent,FreeCAD
from FreeCAD import Vector , Placement

class Door_D1(ArchComponent.Component):
    def __init__(self,obj):
        ArchComponent.Component.__init__(self,obj)

        obj.addProperty("App::PropertyDistance","Width","Door","The Width of this door")
        obj.addProperty("App::PropertyDistance","Height","Door","The height of this door")
        obj.addProperty("App::PropertyDistance","FrameThickness","Door","The Thickness of this door's frame")
        obj.addProperty("App::PropertyDistance","FrameWidth","Door","The Width of this door's frame")
        obj.addProperty("App::PropertyDistance","LeafFrameWidth","Door","The Width of this door's frame")

        obj.Role = ['Door']
  
    def getProfile(self,obj,noplacement=True):
        return []

    def getExtrusionVector(self,obj,noplacement=True):
        return FreeCAD.Vector()

    def setShapeCode(self , ShapeCode):
        pass
        
    def execute(self,obj): 
        pl = obj.Placement
        H1 = obj.Height
        W1 = obj.Width
        t = obj.FrameThickness
        w = obj.FrameWidth

        
        # Door Frame
        import Part
        points = []
        points.append(Vector(0,0,0))
        points.append(Vector(0,0,H1))
        points.append(Vector(W1,0,H1))
        points.append(Vector(W1,0,0))
        points.append(Vector(W1-w,0,0))
        points.append(Vector(W1-w,0,H1-w))
        points.append(Vector(w,0,H1-w))
        points.append(Vector(w,0,0))
        points.append(Vector(0,0,0))
        lines = []
        for i in range(1, len(points)):
            lines.append(Part.Line(points[i],points[i-1]))
        
        S1 = Part.Shape(lines)
        W = Part.Wire(S1.Edges)
        face = Part.Face(W)
        DoorFrame = face.extrude(Vector(0,t,0))

        shapes = []
        shapes.append(DoorFrame)

        # Door Leaf Frame
        w2 = obj.LeafFrameWidth   # width of frame of leaf
        h2 = H1 - w                 # height of leaf
        W2 = (W1-2*w)/2./2. + w2/2    # width of leaf
        points = []
        points.append(Vector(w,0,0))
        points.append(Vector(w,0,h2))
        points.append(Vector(w+W2,0,h2))
        points.append(Vector(w+W2,0,0))        
        points.append(Vector(w,0,0))

        lines = []
        for i in range(1, len(points)):
            lines.append(Part.Line(points[i],points[i-1]))

        S1 = Part.Shape(lines)
        W = Part.Wire(S1.Edges)
        face = Part.Face(W)

        points2 = []
        points2.append(Vector(w+w2,0,w2))
        points2.append(Vector(w+w2,0,h2-w2))
        points2.append(Vector(w+W2-w2,0,h2-w2))
        points2.append(Vector(w+W2-w2,0,w2))        
        points2.append(Vector(w+w2,0,w2))

        lines2 = []
        for i in range(1, len(points2)):
            lines2.append(Part.Line(points2[i],points2[i-1]))

        S2 = Part.Shape(lines2)
        void_2 = Part.Wire(S2.Edges)
        face2 = Part.Face(void_2)
        face3=face.cut(face2)

        LeafFrame = face3.extrude(Vector(0,30,0))
        LeafFrame.translate(Vector(0,20+30,0))

        LeafFrame2 = LeafFrame.copy()
        LeafFrame2.translate(Vector(W2-w2,-30,0))

        LeafFrame3 = LeafFrame2.copy()
        LeafFrame3.translate(Vector(W2,0,0))

        LeafFrame4 = LeafFrame.copy()
        LeafFrame4.translate(Vector(W1-w-w-W2,0,0))  #W1-w-W2


        shapes.append(LeafFrame)
        shapes.append(LeafFrame2)
        shapes.append(LeafFrame3)
        shapes.append(LeafFrame4)


        # Glass
        
        H3 = H1 - w - w2*2     # height of glass
        W3 = W2 - w2*2        # width of glass
        points = []
        points.append(Vector(0,0,0))
        points.append(Vector(0,0,H3))
        points.append(Vector(W3,0,H3))
        points.append(Vector(W3,0,0))        
        points.append(Vector(0,0,0))

        lines = []
        for i in range(1, len(points)):
            lines.append(Part.Line(points[i],points[i-1]))

        S3 = Part.Shape(lines)
        W3 = Part.Wire(S3.Edges)
        faceFGlass = Part.Face(W3)
        LeafGlass = faceFGlass.extrude(Vector(0,6,0))
        LeafGlass.translate(Vector(w+w2,+100-20-30+15-3,w2))
        #LeafGlass.Transparency = 80
        
        LeafGlass4 = LeafGlass.copy()
        LeafGlass4.translate(Vector(W2*3-w2*2,0,0)) 

        LeafGlass2 = LeafGlass.copy()
        LeafGlass2.translate(Vector(W2-w2,-30,0))
        LeafGlass3 = LeafGlass2.copy()
        LeafGlass3.translate(Vector(W2,0,0))

        shapes.append(LeafGlass)
        shapes.append(LeafGlass2)
        shapes.append(LeafGlass3)
        shapes.append(LeafGlass4)

        if shapes:
            obj.Shape = Part.makeCompound(shapes)
            obj.Placement = pl

class _ViewProviderDoor(ArchComponent.ViewProviderComponent):
    def __init__(self,vobj):
        ArchComponent.ViewProviderComponent.__init__(self,vobj)
        

    def getIcon(self):
        import Arch_rc
        return ":/icons/Arch_Window_Tree.svg"

def makeDoor_D1(width=2600 , height =2050 , FrameWidth= 50,  FrameThickness=100 ,
         LeafFrameWidth=100,placement = (0,0,0) ):
    obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Door")

    Door_D1(obj)
    obj.Width = width
    obj.Height = height
    obj.FrameThickness = FrameThickness
    obj.FrameWidth = FrameWidth
    obj.LeafFrameWidth =LeafFrameWidth

    obj.Placement.Base = Vector(placement)

    if FreeCAD.GuiUp:
        _ViewProviderDoor(obj.ViewObject)
        
    
    return obj

if __name__=="__main__":
    D1 = makeDoor_D1()

    FreeCAD.ActiveDocument.recompute()
    Msg("\nDone!!\n\n")
Door_D1_V1.png
Door_D1_V1.png (348.24 KiB) Viewed 2810 times
DoorD1_ifc.png
DoorD1_ifc.png (302.78 KiB) Viewed 2803 times
D1_Drawing.PNG
D1_Drawing.PNG (12.5 KiB) Viewed 2800 times
Door_D1.FCStd
(19.58 KiB) Downloaded 53 times
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: Custom Door Object

Post by yorik »

at the moment there is no way to set transparency only for a part of an object. Only for the whole object
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Custom Door Object

Post by microelly2 »

this is my way to bring transparence to faces.
http://freecadbuch.de/doku.php?id=blog: ... el_the_egg
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Custom Door Object

Post by chakkree »

@yorik Thank you very much. At first, I will find solution codes from your ArchWindows.py.

@microelly2 Thank for your help. But Glass panel is one part of shape's group. I want to create scripted obeject for Door object that can resize width and height by user.
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: Custom Door Object

Post by yorik »

yorik wrote:at the moment there is no way to set transparency only for a part of an object. Only for the whole object
Not anymore!
viewtopic.php?f=9&t=16476
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Custom Door Object

Post by chakkree »

I created inventor file(door_D1_byHand.iv) for prototype and import to FreeCAD.
By setting material transparency in a group of an object(glass panel).
Next step, try to use coin create elements in scripting object.
Door_import_inventor.png
Door_import_inventor.png (293.04 KiB) Viewed 2678 times
door_D1_byHand.iv
(1.14 KiB) Downloaded 69 times
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Custom Door Object

Post by chakkree »

from "add scene graph by iv-string" @microelly2
viewtopic.php?f=22&t=13828


replace string from file (door_D1_byHand.iv) to varibale(dm)

Code: Select all

import os
from pivy.coin import SoInput,SoDB

dm='''#Inventor V2.1 ascii

Separator {
   Transform {      translation       0 0 1025    }
   
   Separator{
        Material { diffuseColor 0.67 0.33 0}
	    Cube{   width   50   height  100   depth   2050  }
		Transform {      translation       525 0 1000    }
		Cube{   width   1000   height  100   depth   50  }
		Transform {      translation       525 0 -1000    }
		Cube{   width   50   height  100   depth   2050  }
   }
   

   
   Separator{
	  Transform {      translation   525 0 -25    }
	  Material { 
	      diffuseColor 0.33 1.00 1.00
	      transparency 80
	  }
	  Cube{   width   800   height  20   depth   1800  }
   }
  
   Separator{
        Material { diffuseColor 1.00 0.67 0.00}
		Transform {      translation       75 0 -25    }
	    Cube{   width   100   height  40   depth   1800  }
		Transform {      translation       900 0 0    }
		Cube{   width   100   height  40   depth   1800  }
		Transform {      translation       -450 0 -950    }
		Cube{   width   1000   height  40   depth   100  }
		Transform {      translation       0 0 1900    }
		Cube{   width   1000   height  40   depth   100  }

   }
  
}
'''


#tmpname="/tmp/freecad_%s.iv" % os.getpid()
tmpname="d:/temp/freecad_%s.iv" % os.getpid()   # windows 
f=open(tmpname,"w")
f.write(dm)
f.close()
mySceneInput = SoInput()
mySceneInput.openFile(tmpname)
myGraph = SoDB.readAll(mySceneInput)
mySceneInput.closeFile()
sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
sg.addChild(myGraph)
os.remove(tmpname)
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Custom Door Object

Post by chakkree »

Object Door No.1 using coin for display model.
- can not rotate
- can not export svg..etc.
- can not use draft array ,draft clone

Code: Select all

import FreeCAD, FreeCADGui
from pivy import coin
from math import pi

class Door1:
    def __init__(self, obj):
        '''Add some custom properties to our box feature'''
        obj.addProperty("App::PropertyLength","Width","Box","Width of the box").Width=1000.0
        obj.addProperty("App::PropertyLength","Height","Box", "Height of the box").Height=2000.0
        
        obj.addProperty("App::PropertyPlacement","Placement","Base", "")
        
        obj.Proxy = self
    
    def onChanged(self, fp, prop):
        '''Do something when a property has changed'''
        pass
    
    def execute(self, fp):
        '''Do something when doing a recomputation, this method is mandatory'''
        pass

class ViewProviderDoor1:
    def __init__(self, obj):
        '''Set this object to the proxy object of the actual view provider'''
        obj.addProperty("App::PropertyColor","Color","Box","Color of the box").Color=(0.67,0.33,0.0)
        obj.Proxy = self
	
    def attach(self, obj):
        self.shaded = coin.SoGroup()
        self.shaded.setName('Door1')
        self.materialFrame = coin.SoMaterial()
        self.materialGlass = coin.SoMaterial()
        self.materialGlass.transparency.setValue(0.80)
        self.materialGlass.diffuseColor.setValue(0.33,1.0,1.0)
        self.materialLeafFrame = coin.SoMaterial()
        self.materialLeafFrame.transparency.setValue(0.0)
        self.materialLeafFrame.diffuseColor.setValue(1.0,0.670,0.0)
		
		
        self.frame = coin.SoSeparator()
        self.leafframe = coin.SoSeparator()
        self.glass = coin.SoSeparator()
        #leg1 = coin.SoCube()
        #leg2 = coin.SoCube()
        #bar1 =  coin.SoCube()
        #self.frame.addChild(leg1)
        #frame.addChild(bar1)
        #frame.addChild(leg2)
		
		
        self.shaded.addChild(coin.SoTransform())
        self.shaded.addChild(self.materialFrame)
        self.shaded.addChild(self.frame)
        self.shaded.addChild(self.materialGlass)
        self.shaded.addChild(self.glass)
        self.shaded.addChild(self.materialLeafFrame)
        self.shaded.addChild(self.leafframe)
        obj.addDisplayMode(self.shaded,"Shaded");
        
        self.onChanged(obj,"Color")
    
    def updateData(self, fp, prop):
        '''If a property of the handled feature has changed we have the chance to handle this here'''
        # fp is the handled feature, prop is the name of the property that has changed
        placement = fp.getPropertyByName("Placement")
        x = placement.Base.x
        y = placement.Base.y
        z = placement.Base.z
        
        tr_main = self.shaded.getChild(0)
        tr_main.translation.setValue(float(x),float(y),float(z))
        #tr_main.rotation.setValue(coin.SbRotation(coin.SbVec3f(0.0, 0.0, 1.0), pi/2.0))
		
        w = fp.getPropertyByName("Width")
        h = fp.getPropertyByName("Height")
        self.frame.removeAllChildren()
        tr1 = coin.SoTransform()
        tr1.translation.setValue(25/2.,0,float(h)/2)
        leg1 = coin.SoCube()
        leg1.width = float(25)
        leg1.height = float(50)
        leg1.depth = float(h)
        tr2 = coin.SoTransform()
        tr2.translation.setValue(float(w),0,0)
        leg2 = coin.SoCube()
        leg2.width = float(25)
        leg2.height = float(50)
        leg2.depth = float(h)
        tr3 = coin.SoTransform()
        tr3.translation.setValue(-float(w)/2,0,float(h)/2+25/2.)
        bar1 = coin.SoCube()
        bar1.width = float(w)+25
        bar1.height = float(50)
        bar1.depth = float(25)
		
        self.frame.addChild(tr1)
        self.frame.addChild(leg1)
        self.frame.addChild(tr2)
        self.frame.addChild(leg2)
        self.frame.addChild(tr3)
        self.frame.addChild(bar1)
		
        self.glass.removeAllChildren()
        glass = coin.SoCube()
        glass.width = float(w)-75
        glass.height = +6
        glass.depth = float(h)-75
        tr4 = coin.SoTransform()
        tr4.translation.setValue(float(w)/2 + 25/2.,0,float(h)/2)
        self.glass.addChild(tr4)
        self.glass.addChild(glass)
		
        self.leafframe.removeAllChildren()
        leafLeg1 = coin.SoCube()
        leafLeg1.width = 100
        leafLeg1.height = +25
        leafLeg1.depth = float(h)
        tr5 = coin.SoTransform()
        tr5.translation.setValue(100/2.+25 ,0,float(h)/2)
        self.leafframe.addChild(tr5)
        self.leafframe.addChild(leafLeg1)
        leafLeg2 = coin.SoCube()
        leafLeg2.width = 100
        leafLeg2.height = +25
        leafLeg2.depth = float(h)
        tr6 = coin.SoTransform()
        tr6.translation.setValue(float(w)-100-25,0,0)
        self.leafframe.addChild(tr6)
        self.leafframe.addChild(leafLeg2)
        leafBar1 = coin.SoCube()
        leafBar1.width = float(w)-200
        leafBar1.height = +25
        leafBar1.depth = 100
        tr7 = coin.SoTransform()
        tr7.translation.setValue(-float(w)/2+50,0,float(h)/2-50)
        self.leafframe.addChild(tr7)
        self.leafframe.addChild(leafBar1)
        leafBar2 = coin.SoCube()
        leafBar2.width = float(w)-200
        leafBar2.height = +25
        leafBar2.depth = 100
        tr8 = coin.SoTransform()
        tr8.translation.setValue(0,0,-float(h)+100)
        self.leafframe.addChild(tr8)
        self.leafframe.addChild(leafBar2)
        pass
    
    def getDisplayModes(self,obj):
        '''Return a list of display modes.'''
        modes=[]
        modes.append("Shaded")
        return modes
    
    def getDefaultDisplayMode(self):
        '''Return the name of the default display mode. It must be defined in getDisplayModes.'''
        return "Shaded"
    
    def setDisplayMode(self,mode):
        '''Map the display mode defined in attach with those defined in getDisplayModes.\
                Since they have the same names nothing needs to be done. This method is optional'''
        return mode
    
    def onChanged(self, vp, prop):
        '''Here we can do something when a single property got changed'''
        FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
        if prop == "Color":
            c = vp.getPropertyByName("Color")
            self.materialFrame.diffuseColor.setValue(c[0],c[1],c[2])
	
    
    def getIcon(self):
        '''Return the icon in XPM format which will appear in the tree view. This method is\
                optional and if not defined a default icon is shown.'''
        return """
            /* XPM */
            static const char * ViewProviderBox_xpm[] = {
            "16 16 6 1",
            "   c None",
            ".  c #141010",
            "+  c #615BD2",
            "@  c #C39D55",
            "#  c #000000",
            "$  c #57C355",
            "        ........",
            "   ......++..+..",
            "   .@@@@.++..++.",
            "   .@@@@.++..++.",
            "   .@@  .++++++.",
            "  ..@@  .++..++.",
            "###@@@@ .++..++.",
            "##$.@@$#.++++++.",
            "#$#$.$$$........",
            "#$$#######      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            " #$#$$$$$#      ",
            "  ##$$$$$#      ",
            "   #######      "};
            """
    
    def __getstate__(self):
        '''When saving the document this object gets stored using Python's json module.\
                Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
                to return a tuple of all serializable objects or None.'''
        return None
    def __setstate__(self,state):
        '''When restoring the serialized object from document we have the chance to set some internals here.\
                Since no data were serialized nothing needs to be done here.'''
        return None

def makeDoor1():
    doc=FreeCAD.ActiveDocument
    a=doc.addObject("App::FeaturePython","Door1")
    Door1(a)
    ViewProviderDoor1(a.ViewObject)
    return a

if __name__=='__main__':
    door1 = makeDoor1()
    #Msg(door1.ViewObject.IV)
    
    FreeCAD.ActiveDocument.recompute()
    #Msg('Done!\n\n')
Door1_coin.png
Door1_coin.png (335.62 KiB) Viewed 2034 times
Post Reply