Document & Visualize forum
cancel
Showing results for 
Search instead for 
Did you mean: 

Custom classification creation

bouhmidage
Enthusiast

Hello,

As far asvi know, the only method to create a custom classification system is to use classification window inside Archicad, create classes one by one, number them, oh wait, if i want to reorder my classes, it will be a nightmare....

 

I tried to generate classifications by mapping an excel tible using Archicad classification map, but it does not export, Archicad xml mapping uses list of lists mapping and this is not supported by excel.

 

Antone explored this field and had some good results ??

 

Also classification from revit can't be loaded in Archicad 

 

A better classification manager should be inttoduced soon, 

AMD Ryzen 9 3900X, 32 GB RAM, RTX 3080 10 GB

Archicad 23

Windows 10 professional

https://www.behance.net/Nuance-Architects
11 REPLIES 11

stefan
Booster

I've created Archicad Classification files in the past, from Excel. I started from an existing system in Excel and added a few formulas to turn them into lines of XML, ready to paste into a clean ascii document. This can be loaded in Archicad.

 

There was some trial and error involved to also have the tree included, to be honest. But much faster to prepare in Excel.

 

If the "tree" is not too long, you can simplify things by only preparing a flat list and create the tree inside Archicad with dragging and dropping items onto branches. And then export the XML again.

 

Excel setupExcel setup

--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2020/Rhino6/Unity2020/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win10
ARCHICAD-user since 1998

bouhmidage
Enthusiast

That sounds good , i can give it a try , but i don't know how xml language works exaactly hhh

AMD Ryzen 9 3900X, 32 GB RAM, RTX 3080 10 GB

Archicad 23

Windows 10 professional

https://www.behance.net/Nuance-Architects

I did this test, and didn't work, 

if all levels are set to 1, it works perfectly 

<here is the problem please ?

EXCEL_2021-09-08_22-34-42.jpg

AMD Ryzen 9 3900X, 32 GB RAM, RTX 3080 10 GB

Archicad 23

Windows 10 professional

https://www.behance.net/Nuance-Architects

Laszlo Nagy
Community Admin
Community Admin

2 observations from me:

  • The "Levels" column values do not correspond with the Item part column when items consist of 3 or 4 levels.
  • Also, Item 1.6 should be generated before you generate Item 1.6.1, Item 1.7 should be generated before you generate Item 1.7.2, and so on,
....................................................................................................
Laszlo Nagy, Lead Moderator, Community Admin
Get Archicad Tips at https://twitter.com/laszlonagy
AMD Ryzen 1700X CPU, 48 GB RAM, NVidia GTX 1060 6GB, 500 GB NVMe SSD
2x28" (2560x1440), WIN10 PRO ENG, AC20-AC25
Loving Archicad since 1995

Yes, numbering is chaotic, the most important thing is level number, i put 1and 2 to simplify things,

If i put 1 in all levels, it loads in Archicad,

 

AMD Ryzen 9 3900X, 32 GB RAM, RTX 3080 10 GB

Archicad 23

Windows 10 professional

https://www.behance.net/Nuance-Architects

I had to include many steps to turn the "text" fragments into more structured numbers for branches & leafs. Formulas like LEN, RIGHT, LEFT, FIND etc... - easier to manage if you spread them over multiple columns.

 

This is totally dependent on the breakdown structure you are using.

I had to split a string like "02.21.1b planning des travail CCTB 01.02" into

  • Code = 02.21.1
  • Description = Planning des travaux
  • Backcode = CCTB 01.02 (which I needed to know how many characters to remove at the back of the string)

Then I had to "escape" some characters (like > < and &) to reach valid XML.

Excel SUBSTITUTE formula to the rescue.

 

Then a concatenation into an item XML fragment (the dots were the code and description which I just extracted).

<item><ID>...</ID><Name>...</Name><Description/><Availability>ModelElement</Availability>

 

Then deep parent/Child trickery to understand from each line, based on the "code":

  • IsParent = true for toplevel codes (= no subcodes, only one field is set)
  • IsFirstChild = true if our code has more fields than the one above (e.g. 00.01 is longer than 00)
  • IsLastChild = true if our code has more fields than the one below (e.g. 01.05 is longer than 02)
  • Level = lots of nested IF statements - totally dependent on your classification system (e.g. 01.02.04 has 4 fields, but I had a situation where some fields could have additional characters, such as 01.02.04b)
  • Prefix = add <children> if IsFirstChild
  • ItemPart = the XML fragment above
  • Children = add </Children></Item> if not IsParent
  • PostFix = add </Children></Item> if IsLastChild, but repeat it (!) as many times as current level minus the level of the row below

Finally concatenate the Prefix, ItemPart, Children and Postfix strings into an XML fragment.

 

And then, on a separate tab, I also prepared the header and footer of the document.

But you could also just start from an existing one or edit that directly inside Archicad.

Yup... That's about it.

 

--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2020/Rhino6/Unity2020/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win10
ARCHICAD-user since 1998

DGSketcher
Mentor

I have a custom classification system in operation which I built manually in the Classification Manager without much effort. You still have all the data to enter, but dragging for levels etc and editing the codes & descriptions is straight forward. I can't help looking at all that coding and thinking I made the right choice! I guess it depends on how many classifications you have and whether the list is already accessible to Excel.

Apple iMac macOS Big Sur / AC24UKI (most recent builds)

I had a 10K rows Spreadsheet in French... So I decided not to type it in manually.

 

As an alternative, you could prepare a simple flat XML (one code per line) and do the parenting directly inside Archicad via drag and drop. But that was mind-numbing as well for such an amount of items. So I preferred some Excel trickery. But you could script this in Python or C# or any other language, if you are more fluent that way.

 

Many trials and errors, as Archicad is very picky about importing an XML. One mistake and the whole file is rejected.

--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2020/Rhino6/Unity2020/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win10
ARCHICAD-user since 1998

bouhmidage
Enthusiast

Thanks for the description ! 

it works , with a simple exemple, 

now with this classification test it fails, 

i think the PSTFIX column is the tricky one, jumping from level 3 to level 2 causes problems, 

 

Here is the formula i used in the prefix column 

 

=SIERREUR(REPT(SI(L7="T";"</Children></Item>";"");M7-M8);"")

 

EXCEL_2021-09-09_22-39-11.jpg

AMD Ryzen 9 3900X, 32 GB RAM, RTX 3080 10 GB

Archicad 23

Windows 10 professional

https://www.behance.net/Nuance-Architects

stefan
Booster

I have played a bit with a Python script to convert a Revit classification file directly into an Archicad classification XML you can import. It's not perfect and needs to be tuned to the input file (e.g., how the code was set up into fields - but also how to get children inside the right parent), but this one brings you a huge step in the right direction.

 

import copy
import sys
import os
import xml.etree.ElementTree as ET
import datetime

def parse_line(line):
    # Each other line has
    # Code Tab Code:description Tab Number Tab Tab
    # split with tabs
    fields = line.strip().split("\t")
    code = fields[0]
    # print(" -- Code = " + fields[0])
    fields2 = fields[1].strip().split(":")
    description = fields2[1]
    # print(" -- Description = " + fields2[1])
    return (fields[0], fields2[1])


def parse_rvt_assembly(filename):
    print(filename)
    now = datetime.datetime.now()
    # Prepare XML output
    # root = ET.fromstring('<?xml version="1.0" encoding="utf-8" standalone="no"?>')
    BuildingInformation = ET.Element('BuildingInformation')
    Classification = ET.SubElement(BuildingInformation, 'Classification')
    System = ET.SubElement(Classification, 'System')
    Name = ET.SubElement(System, 'Name')
    EditionVersion = ET.SubElement(System, 'EditionVersion')
    EditionDate = ET.SubElement(System, 'EditionDate')
    Year = ET.SubElement(EditionDate, 'Year')
    Year.text = str(now.year)
    Month = ET.SubElement(EditionDate, 'Month')
    Month.text = str(now.month)
    Day = ET.SubElement(EditionDate, 'Day')
    Day.text = str(now.day)
    Description = ET.SubElement(System, 'Description')
    Source = ET.SubElement(System, 'Source')
    Items = ET.SubElement(System, 'Items')

    # Make a dictionary of parents, by chopping of the last field of the ID
    parents = dict()

    # Coming from Revit, it's UTF-16, Little-Endian, CRLF
    with open(filename, 'r', encoding='utf-16-le') as infile:
        # First line = * TAB Title TAB Number TAB TAB
        firstline = infile.readline()
        fields = firstline.strip().split("\t")
        Name.text = fields[1]
        EditionVersion.text = '0.1'

        # parse the items from the Third line
        for line in infile.readlines()[3:]:
            # Ignore all other lines which start with *, # or !
            if line.startswith('#') or line.startswith('*') or line.startswith('!') or line.startswith('@'):
                print("Skipped " + line)
            else:
                print(line.strip())
                fields = parse_line(line)
                # fields[0] = code
                # fields[1] = description

                # And then find out the parent, by splitting the "ID" on dots
                CodeFields = fields[0].split(".")
                # if the code ends with a dot, remove the (empty) last item too
                if (CodeFields[-1] == ''):
                    CodeFields.pop()
                if len(CodeFields) > 0:
                    foundParent = False
                    ParentFields = copy.deepcopy(CodeFields) # otherwise we pop the original
                    while not foundParent:
                        ParentFields.pop()
                        if len(ParentFields) == 0:
                            foundParent = True
                            Item = ET.SubElement(Items, 'Item')
                        else:
                            parentID = ".".join(ParentFields)
                            parentID += "."
                            if parentID in parents:
                                parent = parents[parentID]
                                # add item to children
                                ParentChildren = parent.find('Children')
                                if ParentChildren is None:
                                    ParentChildren = ET.SubElement(parent, 'Children')
                                Item = ET.SubElement(ParentChildren, 'Item')
                                foundParent = True

                # finish
                Code = ET.SubElement(Item, 'ID')
                ItemName = ET.SubElement(Item, 'Name')
                ItemName.text = fields[1]
                ItemChildren = ET.SubElement(Item, 'Children')
                Code.text = fields[0]
                ItemDescription = ET.SubElement(Item, 'Description')
                ItemDescription.text = fields[1]

                # Add to the dictionary
                parents[fields[0]] = Item


    with open("output.xml", "wb") as f:
        # convert xml data to byte object before writing
        b_xml = ET.tostring(BuildingInformation)
        f.write(b_xml)


if __name__ == '__main__':
    filename = sys.argv[1]
    if os.path.isfile(filename):
        parse_rvt_assembly(filename)

 

When applied to my input file, the result looks like the following fragment (after I applied XML-tidy script in a text editor):

 

<?xml version="1.0" encoding="utf-8"?>
<BuildingInformation>
	<Classification>
		<System>
			<Name>RG904 v. 2014 - Regie Der Gebouwen</Name>
			<EditionVersion>0.1</EditionVersion>
			<EditionDate>
				<Year>2021</Year>
				<Month>9</Month>
				<Day>10</Day>
			</EditionDate>
			<Description/>
			<Source/>
			<Items>
				<Item>
					<ID>01.01.</ID>
					<Name>Inrichten van de bouwplaats</Name>
					<Children>
						<Item>
							<ID>01.01.10.</ID>
							<Name>Voorlopige omheining</Name>
							<Children/>
							<Description>Voorlopige omheining</Description>
						</Item>
						<Item>
							<ID>01.01.11.</ID>
							<Name>Voorlopige omheining in overeenstemming met de gemeentelijke voorschriften</Name>
							<Children/>
							<Description>Voorlopige omheining in overeenstemming met de gemeentelijke voorschriften</Description>
						</Item>

 

And this gets imported nicely in Archicad. But your mileage may vary.

 

--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2020/Rhino6/Unity2020/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win10
ARCHICAD-user since 1998

bouhmidage
Enthusiast

Hello again 

I'm not famliar with coding language, but, if your code is strong enough to be an "international translaor" it would be a great tool, 

I'm still working on the excel file, more accurate for me, trying to solve the problem i mentioned before 

AMD Ryzen 9 3900X, 32 GB RAM, RTX 3080 10 GB

Archicad 23

Windows 10 professional

https://www.behance.net/Nuance-Architects

Start a new conversation!

Still looking?

Browse more topics

Back to forum

See latest solutions

Accepted solutions

Start a new discussion!