3DXML File

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!
akeyokey
Posts: 27
Joined: Fri Feb 17, 2017 6:13 pm

3DXML File

Post by akeyokey »

Hello,
I would like to know if there is a way to open 3DXML file using a macro or a trick :?:

Thanks :!:

OS: Windows 7
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.6712 (Git)
Build type: Release
Branch: releases/FreeCAD-0-16
Hash: da2d364457257a7a8c6fb2137cea12c45becd71a
Python version: 2.7.8
Qt version: 4.8.7
Coin version: 4.0.0a
OCC version: 6.8.0.oce-0.17
User avatar
NormandC
Veteran
Posts: 18587
Joined: Sat Feb 06, 2010 9:52 pm
Location: Québec, Canada

Re: 3DXML File

Post by NormandC »

Hi,

3DXML is a proprietary file format invented by Dassault Systèmes. It is only supported by Dassault Systèmes software.

It's apparently a zip container so you could extract its content. But it's doubtful you'll be able to do anything with it.

https://en.wikipedia.org/wiki/3DXML
akeyokey
Posts: 27
Joined: Fri Feb 17, 2017 6:13 pm

Re: 3DXML File

Post by akeyokey »

NormandC wrote: Thu Apr 19, 2018 2:07 am Hi,

3DXML is a proprietary file format invented by Dassault Systèmes. It is only supported by Dassault Systèmes software.

It's apparently a zip container so you could extract its content. But it's doubtful you'll be able to do anything with it.

https://en.wikipedia.org/wiki/3DXML
Ok Thanks, I will try to extract and see what I can do with it.
mantielero
Posts: 17
Joined: Sat Feb 09, 2019 10:15 am

Re: 3DXML File

Post by mantielero »

Sorry to unbury a dead thread.

Just to point out that it looks like the format is documented here.

It woud be great that FreeCAD were capable of reading this files, that are it pretty common in order to share geometries.
aerospaceweeb
Posts: 118
Joined: Fri Apr 09, 2021 3:26 am

Re: 3DXML File

Post by aerospaceweeb »

Hey so, as usual, Dassault's documentation is just as crappy as every other thing they create.

That being said though, it's xml, and I think we could do something here.

Code: Select all

# Just make the 3DRep file into something I can word censored read
# =========================================================

# read the whole 3DRep file.
with open('TessPart_5.3DRep') 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.txt','w')
o.write(str(outfile))
o.close()
there's some code which linebreaks the default terrible 3dxml files into something with proper damn linebreaks, and here's a test file I'm working on.
TessPart_5.3DRep.txt
(488.46 KiB) Downloaded 91 times
I've only worked on FEM module stuff before so I don't really have any clue how to do freeCAD gui stuff, but I'm about to google what proper parametric 3d file formats do exist that are easy to write to and start playing around there.
aerospaceweeb
Posts: 118
Joined: Fri Apr 09, 2021 3:26 am

Re: 3DXML File

Post by aerospaceweeb »

Hey I got something to work.
3dxcrament.png
3dxcrament.png (263.98 KiB) Viewed 4023 times
Using the following code, I can now read a BREP file and import all of the edges in the models as wires.

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()
I'm going to now try and figure out what I can do with the faces.
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: 3DXML File

Post by heda »

cool - could turn out to be the start of something really useful,

when it comes to python, one can always assume that there is some sort of higher level interface to do basic processing, it is just a matter of finding it :-).

for prettify of xml one can use

Code: Select all

from xml.dom import minidom
with open('pretty.xml', 'wt') as f:
    f.write(minidom.parse('myfile.xml').toprettyxml())
if one just wants to extract info from an xml file, the xml.etree.ElementTree battery included module is useful for that (and not much point in prettify then, since it is easy enough to explore/extract nodes from the tree as is). This works great if the xml is well formed, not so well if it is malformed - then one should go to other libraries that are more forgiving on correctness.

specifically for fc, one could use lxml instead, since fc already has it as an dependency.

using batteries included I think your code could be drastically shorter and still do the same :-)
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: 3DXML File

Post by keithsloan52 »

heda wrote: Sun Sep 26, 2021 8:17 am
if one just wants to extract info from an xml file, the xml.etree.ElementTree battery included module is useful for that (and not much point in prettify then, since it is easy enough to explore/extract nodes from the tree as is). This works great if the xml is well formed, not so well if it is malformed - then one should go to other libraries that are more forgiving on correctness.

specifically for fc, one could use lxml instead, since fc already has it as an dependency.
I would strongly recommend that you use lxml to parse the file https://lxml.de and as pointed out several other parts of FreeCAD already make use of the lxml library.
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: 3DXML File

Post by heda »

as inspiration for an lxml variant, here is one with py std-lib,
works on the attached file.

Code: Select all

import Part
from PySide import QtGui
import xml.etree.ElementTree as ET

filename, filt = QtGui.QFileDialog.getOpenFileName(filter='*.3DRep')

if not filename:
    raise ValueError('Need to select a 3DRep file.')

doc = App.ActiveDocument

tree = ET.parse(filename)
root = tree.getroot()

floatify = lambda p: tuple((float(i) for i in p.split()))
for xroot in root.findall('{*}Root/{*}Rep'):
    edges = xroot.find('{*}Rep/{*}Edges')
    group = doc.addObject('App::DocumentObjectGroup','Group')
    for poly in edges:
        verts = [floatify(v) for v in poly.get('vertices').split(',')]
        pl = Part.makePolygon(verts)
        obj = doc.addObject('Part::Feature', 'Shape')
        obj.Shape = pl
        group.addObject(obj)
doc.recompute()
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: 3DXML File

Post by keithsloan52 »

heda wrote: Mon Sep 27, 2021 9:01 pm as inspiration for an lxml variant, here is one with py std-lib,
works on the attached file.
Except that is using xml NOT lxml which is faster and has more option.

Try changing

Code: Select all

import xml.etree.ElementTree as ET
to

Code: Select all

 import lxml.etree.ElementTree as ET
Post Reply