glider workbench

Show off your FreeCAD projects here!
User avatar
Zolko
Posts: 1103
Joined: Mon Dec 17, 2018 10:02 am

Re: glider workbench

Postby Zolko » Wed Jan 08, 2020 11:01 am

looo wrote:
Sun Jan 05, 2020 6:33 pm
There are also more useful applications:
would this workbench, and/or any of the related tools (OpenGlider ?), work also for hang-gliders ? In other words, can this calculate aerodynamical forces and the resulting deformation on partially sustained tissue ? The main difference between a paraglider and a hang-glider is that for the latter the leading-edge is rigid, formed by some stiff "rod" (or similar).
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here
User avatar
looo
Posts: 3482
Joined: Mon Nov 11, 2013 5:29 pm

Re: glider workbench

Postby looo » Wed Jan 08, 2020 7:47 pm

Zolko wrote:
Wed Jan 08, 2020 11:01 am
would this workbench, and/or any of the related tools (OpenGlider ?), work also for hang-gliders ? In other words, can this calculate aerodynamical forces and the resulting deformation on partially sustained tissue ? The main difference between a paraglider and a hang-glider is that for the latter the leading-edge is rigid, formed by some stiff "rod" (or similar).
No, openglider and the corresponding workbench for freecad supports only ram-air designs like paragliders, parachutes, and kites. Also, it doesn't allow to compute fluid-structure interactions. (At least this is not possible yet).
User avatar
rubylion
Posts: 14
Joined: Sat Sep 28, 2019 1:28 am
Location: Berlin

Re: glider workbench

Postby rubylion » Thu Jan 16, 2020 6:44 pm

Thanx. I already seen this approach. I'm not sure if this is the solution, but it's a fact that the momentarily used Windgenerators are not as efficient as could be. Also the possibility of storeing the windenergy in Hydrogen is not explored enough in my opinion. Even if the coefficient of H2 is not that high, because of the transferency loss, wind still is a free and massive source of energy. Scientists have proposed to store the hydrogen in the already exisring gas-pipe system, for quite a while now. But nothing happens and the puplic is left in the dark. It's no problem at all, and we would have enough capacity for everything. An alternative to H2 is Windgas, which is H2 comibined with another gas. Stil being environmentaly safe. Also the electrification of cars and such, will only be a short interrim, creating money for the industry, mainley because of the batteries that are needed and the resources to build them. Electric cars are not environmentaly friendly at all. The longterm will and must be hydrogen. Combined with a society that is able to use public transportablity much more versatile, in the near future, self-driving cars f.e., can reduce the carbon footprint of mankind to an absolute minimum. But you know... Money makes the world go down(round?).
Of course this is another topic and exceeds this thread.
User avatar
looo
Posts: 3482
Joined: Mon Nov 11, 2013 5:29 pm

Re: glider workbench

Postby looo » Tue Feb 25, 2020 1:51 pm

As many struggled with installing openglider, there is now a (free :D ) appimage available to test the openglider integration in freecad. If wanted I will add the same for osx.
User avatar
Kunda1
Posts: 8772
Joined: Thu Jan 05, 2017 9:03 pm

Re: glider workbench

Postby Kunda1 » Wed Sep 02, 2020 1:01 pm

looo wrote:
Tue Feb 25, 2020 1:51 pm
As many struggled with installing openglider, there is now a (free :D ) appimage available to test the openglider integration in freecad. If wanted I will add the same for osx.
Wow, how did I miss that update. Please link to it?
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
User avatar
looo
Posts: 3482
Joined: Mon Nov 11, 2013 5:29 pm

Re: glider workbench

Postby looo » Wed Sep 02, 2020 8:55 pm

Kunda1 wrote:
Wed Sep 02, 2020 1:01 pm
looo wrote:
Tue Feb 25, 2020 1:51 pm
As many struggled with installing openglider, there is now a (free :D ) appimage available to test the openglider integration in freecad. If wanted I will add the same for osx.
Wow, how did I miss that update. Please link to it?
https://github.com/booya-at/OpenGlider/ ... tag/0.05.1

and a small tutorial:
https://booya-at.github.io/openglider-tutorial/

also work on integrating another open paragliding backend has started. It is called leparaglide:
http://www.laboratoridenvol.com/
https://anaconda.org/conda-forge/leparagliding/files
User avatar
looo
Posts: 3482
Joined: Mon Nov 11, 2013 5:29 pm

Re: glider workbench

Postby looo » Fri Sep 18, 2020 1:21 pm

crosspost:
thomas-neemann wrote:
Fri Sep 18, 2020 1:06 pm
looo wrote:
Fri Sep 18, 2020 1:03 pm
... Ich scheitere gerade an einem dxf-import der in librecad nicht einmal eine sekunde benötigt in FreeCAD aber geschätzt 15 min....
das finde ich spannend, gibt es eine test-datei zum downloaden?

lgt homas
bitte sehr: https://github.com/looooo/leparagliding ... lep-3d.dxf

ot: es ist ein versuch leparagliding als backend für die glider workbench zu verwenden. leparagliding gibt alles als dxf aus (hauptsächlich linien). Das Problem ist, dass das elends viele Elemente sind und FreeCAD daraus occt-shapes erstellt welche nicht gerade "lightweight" sind. Ich hab schon immer dafür plädiert eine occt-unabhängige geometrie für solche dxf-imports zu verwenden. Man kann es ja FreeCAD intern immer noch in shapes umwandeln falls erwünscht. Bei mir geht es einfach nur um den Abgleich openglider / leparagliding. Da brauuch ich keine großartigen occt-funktionen.
User avatar
thomas-neemann
Posts: 1548
Joined: Wed Jan 22, 2020 6:03 pm

Re: glider workbench

Postby thomas-neemann » Fri Sep 18, 2020 6:09 pm

looo wrote:
Fri Sep 18, 2020 1:21 pm
ich konnte die datei in 2,5 minuten laden, wenn ich freecad unter linux mit höchster priorität laufen lasse. (auf einem 7 jahre alten büro-pc)
wenn ich daraus mit part einen verbund mache und als fcstd abspeichere, läd die datei nach freecad-neustart in 8 sekunden. das halte ich für brauchbar.

lg thomas
User avatar
Gift
Posts: 521
Joined: Tue Aug 18, 2015 10:08 am
Location: Germany, Sauerland

Re: glider workbench

Postby Gift » Fri Sep 18, 2020 6:45 pm

Ich hatte eine einfache Lib geschrieben. Die Klassen kannst du nach Bedarf anpassen.
I wrote a simple lib. The classes can you change.

fc_dxflib.py

Code: Select all

# a FreeCAD Library 

#***************************************************************************
#*   (c) Benjamin Alterauge (gift) 2018 - 2020                             *   
#*                                                                         *
#*   This file is part of the FreeCAD CAx development system.              *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU Lesser General Public License (LGPL)    *
#*   as published by the Free Software Foundation; either version 2 of     *
#*   the License, or (at your option) any later version.                   *
#*   for detail see the LICENCE text file.                                 *
#*                                                                         *
#*   FreeCAD is distributed in the hope that it will be useful,            *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU Lesser General Public License for more details.                   *
#*                                                                         *
#*   You should have received a copy of the GNU Library General Public     *
#*   License along with FreeCAD; if not, write to the Free Software        *
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
#*   USA                                                                   *
#*                                                                         *
#***************************************************************************

import numpy as np
import FreeCAD

GC_ENTITY_TYPE = 0
GC_HANDLE      = 5
GC_DOUBLE      = np.concatenate((np.arange(10,59),np.arange(140,147)))
GC_INT16       = np.concatenate((np.arange(60,79),np.arange(170,175),np.arange(400,409),np.arange(1060,1070)))
GC_INT32       = np.concatenate((np.arange(90,99),[1071]))
GC_X           = 10
GC_Y           = 20
GC_Z           = 30

class DXFEntity:

    def __init__(self, et=''): self.groupcodes = {GC_ENTITY_TYPE : et}
    def set(self, gc, vl):     self.groupcodes[gc] = vl
    def value(self, gc):       return self.groupcodes[gc]
    def type(self):            self.groupcodes[GC_ENTITY_TYPE]
    def handle(self):          self.groupcodes[GC_HANDLE]
    
    def set_list(self, gc, vl):
        if gc in self.groupcodes:
            self.groupcodes[gc].append(vl)
        else:
            self.groupcodes[gc] = [vl] 

class DXFPolyline(DXFEntity):
    def __init__(self, et='POLYLINE'): 
        self.vertexes = []
        DXFEntity.__init__(self, et)

    def add_vertex(self, obj):
        self.vertexes.append(obj)

    def get_vertexes(self):
        return self.vertexes

    def count_vertexes(self):
        return len(self.vertexes)

    def to_wire(self):
        import Part
        dw = Part.makePolygon([i.vector() for i in self.get_vertexes()])
        Part.show(dw)
        return dw

    def to_points(self):
        import Points
        pp=Points.Points()
        pp.addPoints([i.vector() for i in self.get_vertexes()])
        Points.show(pp)
        return pp

    def to_fc(self):
        return self.to_wire()

    def is_polyline(self):
        return True

class DXFVertex(DXFEntity):
    def __init__(self, et='VERTEX'):
        DXFEntity.__init__(self, et)
        self.set(GC_X, 0.0)
        self.set(GC_Y, 0.0)
        self.set(GC_Z, 0.0)

    def x(self): return self.value(GC_X)
    def y(self): return self.value(GC_Y)
    def z(self): return self.value(GC_Z)
    def vector(self): return FreeCAD.Vector(self.x(), self.y(), self.z())
    def is_vertex(): return True

class DXFLine(DXFEntity):
    def __init__(self, et='LINE'):
        DXFEntity.__init__(self, et)
        self.set(GC_X, 0.0)
        self.set(GC_Y, 0.0)
        self.set(GC_Z, 0.0)
        self.set(GC_X+1, 0.0)
        self.set(GC_Y+1, 0.0)
        self.set(GC_Z+1, 0.0)

    def x1(self): return self.value(GC_X)
    def y1(self): return self.value(GC_Y)
    def z1(self): return self.value(GC_Z)
    def x2(self): return self.value(GC_X+1)
    def y2(self): return self.value(GC_Y+1)
    def z2(self): return self.value(GC_Z+1)
    # def vector(self): return FreeCAD.Vector(self.x(), self.y(), self.z())
    def is_line(self): return True

    
class DXFFACE(DXFEntity):
    def __init__(self, et='PLANE'):
        DXFEntity.__init__(self, et)
        self.set(GC_X, 0.0)
        self.set(GC_Y, 0.0)
        self.set(GC_Z, 0.0)
        self.set(GC_X+1, 0.0)
        self.set(GC_Y+1, 0.0)
        self.set(GC_Z+1, 0.0)
        self.set(GC_X+2, 0.0)
        self.set(GC_Y+2, 0.0)
        self.set(GC_Z+2, 0.0)
        self.set(GC_X+3, 0.0)
        self.set(GC_Y+3, 0.0)
        self.set(GC_Z+3, 0.0)

    def x1(self): return self.value(GC_X)
    def y1(self): return self.value(GC_Y)
    def z1(self): return self.value(GC_Z)
    def x2(self): return self.value(GC_X+1)
    def y2(self): return self.value(GC_Y+1)
    def z2(self): return self.value(GC_Z+1)
    def x3(self): return self.value(GC_X+2)
    def y3(self): return self.value(GC_Y+2)
    def z3(self): return self.value(GC_Z+2)
    def x4(self): return self.value(GC_X+3)
    def y4(self): return self.value(GC_Y+3)
    def z4(self): return self.value(GC_Z+3)
    def is_plane(true): return True

class DXFSpline(DXFEntity):
    def __init__(self, et='VERTEX'):
        DXFEntity.__init__(self, et)
        
    def flag(self): return self.value(70)
    def is_spline(self): return True
    def is_closed(self): return (self.value(70)<<1)
    def is_periodic(self): return (self.value(70)<<2)
    def is_rational(self): return (self.value(70)<<4)
    def is_planar(self): return (self.value(70)<<8)
    def is_linear(self): return (self.value(70)&16) > 0
    
    def to_polygon(self):
        import FreeCAD, Part
        poly = [] 
        for i in np.arange(len(self.value(GC_X))):
            poly.append(FreeCAD.Vector(self.value(GC_X)[i],self.value(GC_Y)[i],self.value(GC_Z)[i]))

        poly.pop(0)
        
        try:
            if (poly > 2):
                return Part.makePolygon(poly)
            elif (poly == 2):
                return Part.LineSegment(poly)
            else:
                return None
        except Part.OCCError:
            return None
        

def dublette(dxffile):
    code  = int(dxffile.readline())
    value = dxffile.readline().strip()
    if (code == GC_ENTITY_TYPE):
        value.upper()
    elif code in GC_INT16:
        value = np.int16(value)
    elif code in GC_INT32:
        value = np.int32(value)
    elif code in GC_DOUBLE:
        value = np.float64(value)  
    return [code, value]

def prase(filename):
    entries = { 'POLYLINE': 0, 'VERTEX': 0, 'LINE': 0, 'SPLINE': 0, '3DFACE':0 }
    result = []
    dxffile = open(filename,'r')
    while True:
        code, value = dublette(dxffile)
        if (value=='EOF'): break
        elif (value=='SECTION'):
            code, value = dublette(dxffile)
            if (value=='ENTITIES'): 
                polyline = None
                code, value = dublette(dxffile)
                while not (value=='ENDSEC'):
                    if (code==GC_ENTITY_TYPE):
                        support = 0
                        if (value=='POLYLINE'):
                            polyline = DXFPolyline()
                            result.append(polyline)
                            support = 1
                        elif (value=='VERTEX'):
                           if polyline:
                            result.append(DXFVertex())   
                            polyline.add_vertex(result[-1]) 
                            support = 1
                        elif (value=='3DFACE'):
                            result.append(DXFFACE())   
                            support = 1
                        elif (value=='SEQEND'):
                            if polyline:
                                polyline = None 
                        elif (value=='LINE'):
                            result.append(DXFLine()) 
                            support = 1
                        elif (value=='SPLINE'):
                            result.append(DXFSpline()) 
                            support = 2
                        if support>0:
                            entries[value] += 1
                    else:
                        if (support==1):
                            result[-1].set(code, value)
                        elif (support==2):
                            if code in [10,20,30,40]:
                                result[-1].set_list(code, value)
                            else:
                                result[-1].set(code, value)

                    code, value = dublette(dxffile)
    dxffile.close()
    return [entries, result]
Die Datei besteht nur aus Linien:
The file contains only lines:

Code: Select all

>>> import fc_dxflib as dxf
>>> entries, results = dxf.prase('/Users/bal/Downloads/lep-3d.dxf')
>>> entries
{'POLYLINE': 0, 'VERTEX': 0, 'LINE': 10793, 'SPLINE': 0, '3DFACE': 0}
>>> results[0].x1()
24.36
>>> hasattr(results[0],'is_line') 
True
User avatar
Gift
Posts: 521
Joined: Tue Aug 18, 2015 10:08 am
Location: Germany, Sauerland

Re: glider workbench

Postby Gift » Fri Sep 18, 2020 8:23 pm

fc_dxflib.py New version

Code: Select all

# a FreeCAD Library 

#***************************************************************************
#*   (c) Benjamin Alterauge (gift) 2018 - 2020                             *   
#*                                                                         *
#*   This file is part of the FreeCAD CAx development system.              *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU Lesser General Public License (LGPL)    *
#*   as published by the Free Software Foundation; either version 2 of     *
#*   the License, or (at your option) any later version.                   *
#*   for detail see the LICENCE text file.                                 *
#*                                                                         *
#*   FreeCAD is distributed in the hope that it will be useful,            *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU Lesser General Public License for more details.                   *
#*                                                                         *
#*   You should have received a copy of the GNU Library General Public     *
#*   License along with FreeCAD; if not, write to the Free Software        *
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
#*   USA                                                                   *
#*                                                                         *
#***************************************************************************

import numpy as np
import FreeCAD, Part

GC_ENTITY_TYPE = 0
GC_HANDLE      = 5
GC_DOUBLE      = np.concatenate((np.arange(10,59),np.arange(140,147)))
GC_INT16       = np.concatenate((np.arange(60,79),np.arange(170,175),np.arange(400,409),np.arange(1060,1070)))
GC_INT32       = np.concatenate((np.arange(90,99),[1071]))
GC_X           = 10
GC_Y           = 20
GC_Z           = 30

class DXFEntity:

    def __init__(self, et=''): self.groupcodes = {GC_ENTITY_TYPE : et}
    def set(self, gc, vl):     self.groupcodes[gc] = vl
    def value(self, gc):       return self.groupcodes[gc]
    def type(self):            self.groupcodes[GC_ENTITY_TYPE]
    def handle(self):          self.groupcodes[GC_HANDLE]
    
    def set_list(self, gc, vl):
        if gc in self.groupcodes:
            self.groupcodes[gc].append(vl)
        else:
            self.groupcodes[gc] = [vl] 

class DXFPolyline(DXFEntity):
    def __init__(self, et='POLYLINE'): 
        self.vertexes = []
        DXFEntity.__init__(self, et)

    def add_vertex(self, obj):
        self.vertexes.append(obj)

    def get_vertexes(self):
        return self.vertexes

    def count_vertexes(self):
        return len(self.vertexes)

    def to_wire(self):
        import Part
        dw = Part.makePolygon([i.vector() for i in self.get_vertexes()])
        Part.show(dw)
        return dw

    def to_points(self):
        import Points
        pp=Points.Points()
        pp.addPoints([i.vector() for i in self.get_vertexes()])
        Points.show(pp)
        return pp

    def to_fc(self):
        return self.to_wire()

    def is_polyline(self):
        return True

class DXFVertex(DXFEntity):
    def __init__(self, et='VERTEX'):
        DXFEntity.__init__(self, et)
        self.set(GC_X, 0.0)
        self.set(GC_Y, 0.0)
        self.set(GC_Z, 0.0)

    def x(self): return self.value(GC_X)
    def y(self): return self.value(GC_Y)
    def z(self): return self.value(GC_Z)
    def vector(self): return FreeCAD.Vector(self.x(), self.y(), self.z())
    def is_vertex(): return True

class DXFLine(DXFEntity):
    def __init__(self, et='LINE'):
        DXFEntity.__init__(self, et)
        self.set(GC_X, 0.0)
        self.set(GC_Y, 0.0)
        self.set(GC_Z, 0.0)
        self.set(GC_X+1, 0.0)
        self.set(GC_Y+1, 0.0)
        self.set(GC_Z+1, 0.0)

    def x1(self): return self.value(GC_X)
    def y1(self): return self.value(GC_Y)
    def z1(self): return self.value(GC_Z)
    def x2(self): return self.value(GC_X+1)
    def y2(self): return self.value(GC_Y+1)
    def z2(self): return self.value(GC_Z+1)
    def is_line(self): return True
    def toEdge(self): return Part.makeLine((self.x1(), self.y1(), self.z1()), (self.x2(), self.y2(), self.z2()))

    
class DXFFACE(DXFEntity):
    def __init__(self, et='PLANE'):
        DXFEntity.__init__(self, et)
        self.set(GC_X, 0.0)
        self.set(GC_Y, 0.0)
        self.set(GC_Z, 0.0)
        self.set(GC_X+1, 0.0)
        self.set(GC_Y+1, 0.0)
        self.set(GC_Z+1, 0.0)
        self.set(GC_X+2, 0.0)
        self.set(GC_Y+2, 0.0)
        self.set(GC_Z+2, 0.0)
        self.set(GC_X+3, 0.0)
        self.set(GC_Y+3, 0.0)
        self.set(GC_Z+3, 0.0)

    def x1(self): return self.value(GC_X)
    def y1(self): return self.value(GC_Y)
    def z1(self): return self.value(GC_Z)
    def x2(self): return self.value(GC_X+1)
    def y2(self): return self.value(GC_Y+1)
    def z2(self): return self.value(GC_Z+1)
    def x3(self): return self.value(GC_X+2)
    def y3(self): return self.value(GC_Y+2)
    def z3(self): return self.value(GC_Z+2)
    def x4(self): return self.value(GC_X+3)
    def y4(self): return self.value(GC_Y+3)
    def z4(self): return self.value(GC_Z+3)
    def is_plane(true): return True

class DXFSpline(DXFEntity):
    def __init__(self, et='VERTEX'):
        DXFEntity.__init__(self, et)
        
    def flag(self): return self.value(70)
    def is_spline(self): return True
    def is_closed(self): return (self.value(70)<<1)
    def is_periodic(self): return (self.value(70)<<2)
    def is_rational(self): return (self.value(70)<<4)
    def is_planar(self): return (self.value(70)<<8)
    def is_linear(self): return (self.value(70)&16) > 0
    
    def to_polygon(self):
        import FreeCAD, Part
        poly = [] 
        for i in np.arange(len(self.value(GC_X))):
            poly.append(FreeCAD.Vector(self.value(GC_X)[i],self.value(GC_Y)[i],self.value(GC_Z)[i]))

        poly.pop(0)
        
        try:
            if (poly > 2):
                return Part.makePolygon(poly)
            elif (poly == 2):
                return Part.LineSegment(poly)
            else:
                return None
        except Part.OCCError:
            return None
        

def dublette(dxffile):
    code  = int(dxffile.readline())
    value = dxffile.readline().strip()
    if (code == GC_ENTITY_TYPE):
        value.upper()
    elif code in GC_INT16:
        value = np.int16(value)
    elif code in GC_INT32:
        value = np.int32(value)
    elif code in GC_DOUBLE:
        value = np.float64(value)  
    return [code, value]

def prase(filename):
    entries = { 'POLYLINE': 0, 'VERTEX': 0, 'LINE': 0, 'SPLINE': 0, '3DFACE':0 }
    result = []
    dxffile = open(filename,'r')
    while True:
        code, value = dublette(dxffile)
        if (value=='EOF'): break
        elif (value=='SECTION'):
            code, value = dublette(dxffile)
            if (value=='ENTITIES'): 
                polyline = None
                code, value = dublette(dxffile)
                while not (value=='ENDSEC'):
                    if (code==GC_ENTITY_TYPE):
                        support = 0
                        if (value=='POLYLINE'):
                            polyline = DXFPolyline()
                            result.append(polyline)
                            support = 1
                        elif (value=='VERTEX'):
                           if polyline:
                            result.append(DXFVertex())   
                            polyline.add_vertex(result[-1]) 
                            support = 1
                        elif (value=='3DFACE'):
                            result.append(DXFFACE())   
                            support = 1
                        elif (value=='SEQEND'):
                            if polyline:
                                polyline = None 
                        elif (value=='LINE'):
                            result.append(DXFLine()) 
                            support = 1
                        elif (value=='SPLINE'):
                            result.append(DXFSpline()) 
                            support = 2
                        if support>0:
                            entries[value] += 1
                    else:
                        if (support==1):
                            result[-1].set(code, value)
                        elif (support==2):
                            if code in [10,20,30,40]:
                                result[-1].set_list(code, value)
                            else:
                                result[-1].set(code, value)

                    code, value = dublette(dxffile)
    dxffile.close()
    return [entries, result]
full example:

Code: Select all

import time
import fc_dxflib as dxf

App.newDocument('TestDxf')

st = time.process_time()
entries, results = dxf.prase('/Users/bal/Downloads/lep-3d.dxf')
pt = time.process_time() - st
pt
st = time.process_time()
geometries = []
for ln in results:
	if hasattr(ln, 'is_line'):
		geometries.append(ln.toEdge())
		

pt = time.process_time() - st
pt
st = time.process_time()
comp = Part.Compound(geometries)
pt = time.process_time() - st
pt
st = time.process_time()
Part.show(comp)
pt = time.process_time() - st
pt


I think it is very fast.