Catia 3DXML (again)

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
mantielero
Posts: 17
Joined: Sat Feb 09, 2019 10:15 am

Re: Catia 3DXML (again)

Post by mantielero »

As found here:

GLC_player support only the ASCII 3DXML.

There is 3 different 3DXML format supported by CATIA V5 :
- Dynamic Tesselation (Exact geometry)
- Static Tesselation (Catia CGR)
- Xml Tesselation (ASCII and published) :arrow: The one used by GLC_Player
The XML bit seems quite easy.

The CGR it looks like it would require reverse engineering AFAIK.
wmayer
Founder
Posts: 20302
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Catia 3DXML (again)

Post by wmayer »

The code base has moved to GH which is slightly newer than that on SF:
https://github.com/laumaya/GLC_lib
https://github.com/laumaya/GLC_Player
aerospaceweeb
Posts: 118
Joined: Fri Apr 09, 2021 3:26 am

Re: Catia 3DXML (again)

Post by aerospaceweeb »

Hey all, I've made progress importing a 3dxml file.

It's reported over here.
https://forum.freecadweb.org/viewtopic. ... 71#p535871

Long story short, here's what I've got.

Code: Select all

import FreeCAD, Part, Fem
from PySide import QtGui
import os
import sys
import re

Vector = App.Vector

def beautify_xml(input_filename): # {{{
    """Just make the 3DRep file into something I can word censored read
    """
    # read the whole 3DRep file.
    with open(input_filename) as f:
        lines = f.readlines()
    f.close()

    # write it out again with linebreaks in the right places
    characters = lines[1]
    outfile = ''
    for i in range(len(characters)):
        # check that not at end
        if i == len(characters)-1:
            continue
        elif characters[i] == ">" and characters[i+1] == "<":
            outfile += ">\n"
        else:
            outfile += characters[i]

    # open output file and put word censored in it
    o = open('outfile.xml','w')
    o.write(str(outfile))
    o.close()

    # make sure I'm on linux
    if sys.platform != "linux":
        raise ValueError("Need to be using linux in order to get xmllint")

    # do the bash command xmllint --format outfile.txt
    os.system("xmllint --format outfile.xml > outfile2.xml")
    os.system("rm outfile.xml")
    os.system("mv outfile2.xml outfile.xml")

    # now read the good file back in with readlines
    with open("outfile.xml") as f:
        lines = f.readlines()
    f.close

    return lines
# }}}

def main(): # {{{
    """ take a 3DRep file and try to get it into freecad
    """
    # get the xml content from the user
    input_filename=QtGui.QFileDialog.getOpenFileName()[0]

    # check to make sure the file is a 3DRep file
    if input_filename.split('/')[-1].split('.')[-1] != '3DRep':
        raise ValueError('Need to select a 3DRep file.')

    xml_content = beautify_xml(input_filename)

    # let's see if we can't make the PolygonalRepType into wires
    # find every line where "PolygonalRepType" starts
    data = []
    i = 0
    while i < len(xml_content)-1:
        line = xml_content[i]
        if "PolygonalRepType" in line:
            i += 1
            line = xml_content[i]
            if "<Edges>" in line:
                escape = False
                while escape == False:
                    i += 1
                    line = xml_content[i]
                    if "</Edges>" in line:
                        escape = True
                    elif "<Polyline vertices=" in line:
                        data.append(line)
        i += 1

    # now have the data for the edges
    # go through it and make the lines for FreeCAD
    vecs = []
    for line in data:
        point_data = line.split('"')[1]
        point_data = point_data.split(',')
        curve = []
        for point in point_data:
            coords = point.split(' ')
            x = float(coords[0])
            y = float(coords[1])
            z = float(coords[2])
            curve.append((x,y,z))
        vecs.append(curve)

    for v in vecs:
        a = Part.makePolygon(v)
        Part.show(a)
    return
# }}}


if __name__ == '__main__':
    main()
This cracks open a manually selected 3DRep file, which is the thing that's inside of the .3dxml container, and reads its simplest entities, the polylines that define the edges of the solid object, to make them again in FreeCAD with basic polygon entities.

This is already a massive step forward, but the file format appears extremely straight forward, so I think I can also get the faces.

Any assistance would be greatly appreciated, as you can see, as I'm quite awful at python.

- Aero
keithsloan52
Veteran
Posts: 2764
Joined: Mon Feb 27, 2012 5:31 pm

Re: Catia 3DXML (again)

Post by keithsloan52 »

aerospaceweeb wrote: Sat Sep 25, 2021 7:22 pm Hey all, I've made progress importing a 3dxml file.

Any assistance would be greatly appreciated, as you can see, as I'm quite awful at python.
Sorry to rain on your parade but I would start again using lxml but using what you have learn't about the file format so far.
Rolling your own processing of xml is not to be recommended
aerospaceweeb
Posts: 118
Joined: Fri Apr 09, 2021 3:26 am

Re: Catia 3DXML (again)

Post by aerospaceweeb »

Thank you Keith, having seen the package recommended by you in the other thread, I couldn't agree more.

When you unzip the .3dxml file, it doesn't seem to have any linebreaks in the constituitive 3DRep files that are there for each "Body" to use the catia lingo.
Screenshot from 2021-09-29 21-48-51.png
Screenshot from 2021-09-29 21-48-51.png (308.4 KiB) Viewed 1846 times
It's all just one godforsaken line!

I originally just made a script to break up the lines for me; and didn't even think to see if this could have been processed in the first place by a tool that I didn't "roll."

Then I saw that I had a file with the linebreaks right, but no indentation. I wasn't even trying to parse it yet, I think.

At no point did I stop inflating the script I'd already made and just re-evaluate. Awful habit, which shall indeed be broken in due time!

Pardon the dead thread bump again, I'll resume the thread over there.
Thanks again Keith
Post Reply