diff --git a/.gitignore b/.gitignore index bad6d9c..66e077c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ __pycache__ notes.txt .vscode test.py -out.xml \ No newline at end of file +out.xml +fnrpl.sh +TODO.txt \ No newline at end of file diff --git a/InitGui.py b/InitGui.py index b582a5a..09f55a0 100644 --- a/InitGui.py +++ b/InitGui.py @@ -22,9 +22,9 @@ def Initialize(self): __dirname__ = os.path.join(FreeCAD.getUserAppDataDir(), "Mod", "RobotDescriptor") #print("got dir:" + __dirname__); - from robot_descriptor import initialize + from robot_descriptor import initialize ,model_editor from robot_descriptor.sdf_elements import world - self.list = ['RD_initialize','world_properties'] + self.list = ['RD_initialize','world_properties','Model_Editor'] self.appendToolbar("RobotDescription",self.list) # creates a new toolbar with your commands self.appendMenu("Robot Description",self.list) # creates a new menu #self.appendMenu(["Robot Description","Tools"],self.list) # appends a submenu to an existing menu diff --git a/robot_descriptor/RD_parser/RD_parse_sdf.py b/robot_descriptor/RD_utils/RD_parse_sdf.py similarity index 99% rename from robot_descriptor/RD_parser/RD_parse_sdf.py rename to robot_descriptor/RD_utils/RD_parse_sdf.py index 414fc9f..1ccf3a7 100644 --- a/robot_descriptor/RD_parser/RD_parse_sdf.py +++ b/robot_descriptor/RD_utils/RD_parse_sdf.py @@ -1,6 +1,6 @@ import xml.etree.ElementTree as ET import os -from .. import RD_globals +from .. import common diff --git a/robot_descriptor/RD_parser/initialize_element_tree.py b/robot_descriptor/RD_utils/initialize_element_tree.py similarity index 96% rename from robot_descriptor/RD_parser/initialize_element_tree.py rename to robot_descriptor/RD_utils/initialize_element_tree.py index c16b4ed..60c8c05 100644 --- a/robot_descriptor/RD_parser/initialize_element_tree.py +++ b/robot_descriptor/RD_utils/initialize_element_tree.py @@ -1,5 +1,5 @@ -from .. import RD_globals +from .. import common from . import RD_parse_sdf @@ -63,7 +63,7 @@ def get_element(self)->ET.Element: t=convdict_2_tree("world.sdf") tree=t.get_tree elm=t.get_elements - e_elem=RD_globals.set_xml_data('linear_velocity',elm,False,[12,9,8]) + e_elem=common.set_xml_data('linear_velocity',elm,False,[12,9,8]) e_elem_t=ET.ElementTree(e_elem) tree.write("out.xml",encoding='utf8',xml_declaration=True) e_elem_t.write("out.xml",encoding='utf8',xml_declaration=True) \ No newline at end of file diff --git a/robot_descriptor/RD_utils/parse_asm4_model.py b/robot_descriptor/RD_utils/parse_asm4_model.py new file mode 100644 index 0000000..45381e5 --- /dev/null +++ b/robot_descriptor/RD_utils/parse_asm4_model.py @@ -0,0 +1,98 @@ +import FreeCAD +import FreeCADGui +import robot_descriptor.common as common +import os + +''' +assembly4 Technical manual +https://github.com/Zolko-123/FreeCAD_Assembly4/blob/master/TECHMANUAL.md + +''' + +def read_assembly(): + links=FreeCAD.ActiveDocument.findObjects("App::Link") + + #get all objects of type part feature + objs=FreeCAD.ActiveDocument.findObjects("Part::Feature") + #get objects in the parts group + parts=FreeCAD.ActiveDocument.Parts.Group + #get fasteners since fasteners might not be accesed through links + #remove objects in parts , coordinate systems + #coordinate systems are removed by checking the MapMode attribute + #hopefully this is will get only fasteners + fasteners=[fast for fast in objs if fast not in parts and not hasattr(fast,'MapMode')] + + #ensure that the link and the fastener are not the same object + #this might occur when the parts folder contains some parts that are used in the assembly + #get link documents + lnk_docs=[lnk.LinkedObject.Document for lnk in links] + for fastener in fasteners: + if fastener.Document not in lnk_docs: + links.append(fastener) + + #links in Assembly4 are of type "App::Link" + #this is a list + #this will store a list of dictionaries + def create_structure(data,dest): + #check the parent objects + #since data is a list of dictionaries + #for every element int he list check if its parent is dest + children=[child for child in data if child["parent"]==dest["name"]] + #return of no children are found + if len (children)==0: + return + #append the children to the current item + for ch in children: + dest["children"].append(ch) + create_structure(data,ch) + + + link_data=[] + #create the root parent + structured_data={} + + #links that have been iterated and not references + non_refs=[] + for child in links: + + name=child.Label + #attachedTo returns a string of the format 'Parent Assembly#LCS_Origin' hence + #hence separating by the the '#' and taking the first element will be the parent + #the 2nd the coordinate system its attached to + parent,attachement=child.AttachedTo.split('#') + #returned type has '#' preceeding the coordinate remove it + attached_by=child.AttachedBy.replace('#','') + if hasattr(child,"LinkedObject") : + #get links which refer to the same document + ref=[r for r in non_refs if r.LinkedObject.Document ==child.LinkedObject.Document] + if len(ref)==1: + #set type as reference i.e its a copy of a link that already exists in the assembly + link_data.append({"ref_label":ref[0].Label,"type":"ref","link":child,"name":name,"parent":parent,"attached_to":attachement,"attached_by":attached_by,'children':[]}) + elif len(ref)==0: + link_data.append({"ref_label":None,"type":"link","link":child,"name":name,"parent":parent,"attached_to":attachement,"attached_by":attached_by,'children':[]}) + non_refs.append(child) + else: + FreeCAD.Console.PrintDeveloperError("parse_asm4:error getting refs no than 1 were found, this is a bug \n") + return + else: + #add fasterners and other too + link_data.append({"ref_label":None,"type":"link","link":child,"name":name,"parent":parent,"attached_to":attachement,"attached_by":attached_by,'children':[]}) + + #create a hierarchial data + if hasattr(child,"LinkedObject"): + if hasattr(child.LinkedObject.Document,"Assembly"): + FreeCAD.Console.PrintError("Sub assemblies not supported yet \n") + return None + root_lcs=FreeCAD.ActiveDocument.findObjects("PartDesign::CoordinateSystem") + structured_data={"ref_label":None,"type":"link","link":None,'name':"Parent Assembly","attachment":None,"coordinate_systems":root_lcs,"children":[]} + + #this will just create a hierarchial data representation + create_structure(link_data,structured_data) + del link_data + del non_refs + return structured_data + + +def get_pose_info(): + pass + diff --git a/robot_descriptor/RD_parser/readme.md b/robot_descriptor/RD_utils/readme.md similarity index 100% rename from robot_descriptor/RD_parser/readme.md rename to robot_descriptor/RD_utils/readme.md diff --git a/robot_descriptor/RD_globals.py b/robot_descriptor/common.py similarity index 89% rename from robot_descriptor/RD_globals.py rename to robot_descriptor/common.py index 161d898..2952876 100644 --- a/robot_descriptor/RD_globals.py +++ b/robot_descriptor/common.py @@ -14,10 +14,10 @@ - +import os import FreeCAD -ICON_PATH=FreeCAD.getUserAppDataDir()+"Mod/RobotDescriptor/robot_descriptor/icons" -UI_PATH=FreeCAD.getUserAppDataDir()+"Mod/RobotDescriptor/robot_descriptor/forms" +ICON_PATH=os.path.join(FreeCAD.getUserAppDataDir()+"Mod","RobotDescriptor","robot_descriptor","icons") +UI_PATH=os.path.join(FreeCAD.getUserAppDataDir()+"Mod","RobotDescriptor","robot_descriptor","forms") DOCUMENT=FreeCAD.ActiveDocument import copy import xml.etree.ElementTree as ET @@ -78,7 +78,7 @@ def set_xml_data(element:ET.Element,tag:str,Is_Attribute:bool,value:Union[dict,f #no need for a loop try: elem=elem_iter.__next__() - except: + except Exception: return None # ensure no dictionaries are sent for non attributes if Is_Attribute is False and isinstance(value,dict) is False: @@ -90,7 +90,7 @@ def set_xml_data(element:ET.Element,tag:str,Is_Attribute:bool,value:Union[dict,f else: #add/edit attributes for key in value.keys(): - elem.set(key,value[key]) + elem.set(key,str(value[key])) return element @@ -114,9 +114,9 @@ def get_value(elem_data): try: try: return int(elem_data) - except: + except Exception: return float(elem_data) - except: + except Exception: return elem_data if Is_Attribute is not True: @@ -126,7 +126,7 @@ def get_value(elem_data): #only a single element exists no need to use a for loop try: elem=elem_iter.__next__() - except: + except Exception: return None if Is_Attribute is False: txt=elem.text @@ -138,9 +138,9 @@ def get_value(elem_data): try: try: return int(elem.attrib[tag[1]]) - except: + except Exception: return float(elem.attrib[tag[1]]) - except: + except Exception: return elem.attrib[tag[1]] #deleting attributes @@ -165,14 +165,17 @@ def parse_dict(root_dict:dict,path:list): # used to track the current index of the path list current_idx=0 + #if only one element is left return it if len(path)==1: if path[-1]=='sdf': return root_dict[path[-1]] + #check if the element exists elif path[-1] in list(root_dict.keys()): return root_dict[path[-1]] else: return None else: + #get the first item in the dictionary parent_key=path[current_idx] current_idx+=1 #child element tag @@ -202,6 +205,7 @@ def update_dictionary(path:list,child_tag:Union[str,None],elem:Union[list,ET.Ele parent_dict=parse_dict(elem_dict,path) if parent_dict is not None: + #this allows update of an element not its children basically None means not the children if child_tag is None: if isinstance(elem,list): parent_dict["elem_str"]=list(map(lambda e:ET.tostring(e,encoding="unicode"),elem)) @@ -245,14 +249,19 @@ def merge_elements(destination_el:ET.Element,source_el:ET.Element,recursive:bool #implemtatation for all other elements #the ones that are not recursive and not physics else: + # Update attributes of destination_el with source_el destination_el.attrib.update(source_el.attrib) + if source_el.text: + destination_el.text = source_el.text + # Merge child elements recursively for child in source_el: - existing_el=destination_el.find(child.tag) + existing_el = destination_el.find(child.tag) if existing_el is not None: - destination_el.remove(existing_el) - destination_el.append(child) + merge_elements(existing_el, child) # Recursively merge the existing element with the new one else: - destination_el.append(child) + # If the element doesn't exist in destination, simply append it + # destination_el.append(child) + pass import math @@ -260,6 +269,8 @@ def merge_elements(destination_el:ET.Element,source_el:ET.Element,recursive:bool class color_pickr: + '''class that implements color picker methods + ''' def __init__(self) -> None: pass #color picker diff --git a/robot_descriptor/forms/collision.ui b/robot_descriptor/forms/collision.ui new file mode 100644 index 0000000..506c6da --- /dev/null +++ b/robot_descriptor/forms/collision.ui @@ -0,0 +1,147 @@ + + + collision + + + + 0 + 0 + 662 + 682 + + + + collision + + + + + + + 644 + 650 + + + + + + + + + laser_retro + + + + + + + false + + + + + + + max_contacts + + + + + + + false + + + + + + + + + include_surface_info + + + + + + + false + + + + 16777215 + 587 + + + + true + + + + + 0 + 0 + 624 + 585 + + + + + + + + + + + + + + collision_laser_retro_cb + toggled(bool) + collision_laser_retro_sp + setEnabled(bool) + + + 94 + 30 + + + 252 + 30 + + + + + collison_max_contacts_cb + toggled(bool) + collision_max_contacts_sp + setEnabled(bool) + + + 409 + 30 + + + 567 + 30 + + + + + include_surface_info_cb + toggled(bool) + collision_scroll + setEnabled(bool) + + + 330 + 60 + + + 330 + 415 + + + + + diff --git a/robot_descriptor/forms/link.ui b/robot_descriptor/forms/link.ui new file mode 100644 index 0000000..a09496d --- /dev/null +++ b/robot_descriptor/forms/link.ui @@ -0,0 +1,1617 @@ + + + link + + + + 0 + 0 + 715 + 668 + + + + link + + + + + + + 697 + 650 + + + + + 16777215 + 650 + + + + + + + + 215 + 100 + + + + + 16777215 + 110 + + + + link states + + + true + + + true + + + + + + If true, the link is affected by gravity + + + gravity + + + + + + + If true, the link is affected by the wind + + + enable_wind + + + + + + + If true, the link is kinematic only + + + kinematic + + + + + + + If true, the link can collide with other links in the model. +Two links within a model will collide if link1.self_collide OR link2.self_collide. +Links connected by a joint will never collide + + + self_collide + + + + + + + + + + + 414 + 600 + + + + true + + + + + 0 + 0 + 440 + 918 + + + + + + + false + + + + 348 + 900 + + + + + 413 + 950 + + + + This link's fluid added mass matrix about the link's origin. + This matrix represents the inertia of the fluid that is dislocated when the + body moves. Added mass should be zero if the density of the surrounding + fluid is negligible with respect to the body's density. + The 6x6 matrix is symmetric, therefore only 21 unique elements can be set. + The elements of the matrix follow the [x, y, z, p, q, r] notation, where + [x, y, z] correspond to translation and [p, q, r] to rotation + + + fluid_added_mass + + + true + + + false + + + + + + + 370 + 200 + + + + + 372 + 190 + + + + x_axis + + + + + 18 + 28 + 344 + 75 + + + + + 340 + 75 + + + + + 344 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + linear_acceleration + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + x + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the X axis due to linear acceleration in the X axis, in kg + + + kg + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + y + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the X axis due to linear acceleration in the Y axis, and vice-versa, in kg. + + + kg + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + Added mass in the X axis due to linear acceleration in the Z axis, and vice-versa, in kg. + + + kg + + + 1000.000000000000000 + + + + + + + + + 12 + 108 + 345 + 75 + + + + + 343 + 75 + + + + + 345 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + angular_acceleration + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + x + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the X axis due to angular acceleration about the X axis, and vice-versa, in kg * m. + + + kgm + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + y + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the X axis due to angular acceleration about the Y axis, and vice-versa, in kg * m. + + + kgm + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the X axis due to angular acceleration about the Z axis, and vice-versa, in kg * m + + + kgm + + + 1000.000000000000000 + + + + + + + + + + + + 370 + 205 + + + + + 372 + 190 + + + + y_axis + + + + + + + 343 + 75 + + + + + 344 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + linear_acceleration + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + y + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Y axis due to linear acceleration in the Y axis, in kg + + + kg + + + 1000.000000000000000 + + + + + + + + 10 + 15 + + + + + 10 + 18 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Y axis due to linear acceleration in the Z axis, and vice-versa, in kg. + + + kg + + + 1000.000000000000000 + + + + + + + + + + + 343 + 75 + + + + + 345 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + angular_acceleration + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + x + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Y axis due to angular acceleration about the X axis, and vice-versa, in kg * m + + + kgm + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + y + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Y axis due to angular acceleration about the Y axis, and vice-versa, in kg * m. + + + kgm + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Y axis due to angular acceleration about the Z axis, and vice-versa, in kg * m. + + + kgm + + + 1000.000000000000000 + + + + + + + + + + + + + + 370 + 190 + + + + + 372 + 190 + + + + z_axis + + + + + + + 343 + 75 + + + + + 344 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + linear_acceleration + + + + + 81 + 32 + 139 + 26 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Z axis due to linear acceleration in the Z axis, in kg. + + + kg + + + 1000.000000000000000 + + + + + + + + + + + + 343 + 75 + + + + + 345 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + angular_acceleration + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + x + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Z axis due to angular acceleration about the X axis, and vice-versa, in kg * m. + + + kgm + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + y + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Z axis due to angular acceleration about the Y axis, and vice-versa, in kg * m. + + + kgm + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass in the Z axis due to angular acceleration about the Z axis, and vice-versa, in kg * m. + + + kgm + + + 1000.000000000000000 + + + + + + + + + + + + + + 370 + 255 + + + + + 372 + 300 + + + + moment + + + + + + + 343 + 75 + + + + + 345 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + moment_x + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + x + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass moment about the X axis due to angular acceleration about the X axis, in kg * m^2. + + + kgm^2 + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + y + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass moment about the X axis due to angular acceleration about the Y axis, and vice-versa, in kg * m^2 + + + kgm^2 + + + 1000.000000000000000 + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass moment about the X axis due to angular acceleration about the Z axis, and vice-versa, in kg * m^2. + + + kgm^2 + + + 1000.000000000000000 + + + + + + + + + + + 343 + 75 + + + + + 345 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + moment_y + + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + y + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass moment about the Y axis due to angular acceleration about the Y axis, in kg * m^2 + + + kgm^2 + + + 1000.000000000000000 + + + + + + + + + + + + 12 + 24 + + + + + 15 + 30 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass moment about the Y axis due to angular acceleration about the Z axis, and vice-versa, in kg * m^2 + + + kgm^2 + + + + + + + + + + + + + 343 + 75 + + + + + 344 + 78 + + + + Added mass in the X axis due to linear acceleration in the x,y,z axes + + + moment_z + + + + + + + + + 10 + 15 + + + + + 10 + 18 + + + + z + + + Qt::AlignCenter + + + + + + + + 90 + 24 + + + + + 100 + 30 + + + + Added mass moment about the Z axis due to angular acceleration about the Z axis, in kg * m^2 + + + kgm^2 + + + + + + + + + + + + + + + + + + + + + + + 217 + 110 + + + + + 16777215 + 120 + + + + Exponential damping of the link's velocity. + + + velocity_decay + + + true + + + false + + + + + + + 35 + 15 + + + + + 45 + 16 + + + + linear + + + + + + + 5 + + + 1000.000000000000000 + + + + + + + + 50 + 25 + + + + + 55 + 27 + + + + angular + + + + + + + 5 + + + 1000.000000000000000 + + + + + + + + + + false + + + + 213 + 70 + + + + + 16777215 + 70 + + + + inertial + + + true + + + false + + + + + + auto + + + + + + + + + + Qt::Vertical + + + + 20 + 481 + + + + + + + + + + + + diff --git a/robot_descriptor/forms/material.ui b/robot_descriptor/forms/material.ui index faf70fa..e2ea512 100644 --- a/robot_descriptor/forms/material.ui +++ b/robot_descriptor/forms/material.ui @@ -1,530 +1,228 @@ - Form - + material + 0 0 - 573 - 690 + 548 + 1545 - Form + material - + - 8 - 82 - 259 - 89 + 0 + 14 + 538 + 1536 - - - 0 - 89 - - - - script - - - true - - - false - - - - - 18 - 28 - 16 - 15 - - - - uri - - - - - - 52 - 24 - 175 - 23 - - - - - - - 12 - 56 - 34 - 15 - - - - name - - - - - - 52 - 52 - 113 - 23 - - - - - - - - 280 - 84 - 259 - 89 - - - - - 0 - 89 - - - - shader - - - true - - - false - - - - - 12 - 32 - 57 - 15 - - - - TextLabel - - - - - - 80 - 28 - 79 - 23 - - - - - vertex - - - - - pixel - - - - - normal_map_object_space - - - - - normal_map_tangent_space - - - - - - - 8 - 60 - 100 - 21 - - - - normal_map - - - - - - 114 - 60 - 113 - 23 - - - - - - - - 10 - 184 - 78 - 24 - - - - - 0 - 24 - - - - render_order - - - - - - 94 - 180 - 83 - 24 - - - - - 0 - 24 - - - - Set render order for coplanar polygons. The higher value will be rendered on top of the other coplanar polygons - - - - - - 8 - 650 - 85 - 24 - - - - - 0 - 24 - - - - lighting - - - - - - 4 - 210 - 520 - 100 - - - - - 520 - 100 - - - 520 - 100 + 538 + 2000 - - background color - - - ambient - - - true - - - false - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - - - - - - 16777215 - 24 - - - - B - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - A - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - R - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - - - + + + - 0 - 24 + 240 + 89 - 16777215 - 24 + 240 + 95 + + script + + + true + + + false + + + + + + uri + + + + + + + + 160 + 16777215 + + + + + + + + + 50 + 24 + + + + name + + + + + + + + 115 + 16777215 + + + + + - - - - - 16777215 - 24 - - - - G - - - Qt::AlignCenter - - - - - + + - 0 - 24 + 240 + 95 - 16777215 - 24 + 240 + 95 + + shader + + + true + + + false + + + + + 12 + 30 + 57 + 16 + + + + type + + + + + + 82 + 26 + 100 + 21 + + + + + 100 + 16777215 + + + + + pixel + + + + + vertex + + + + + normal_map_object_space + + + + + normal_map_tangent_space + + + + + + + 12 + 57 + 100 + 20 + + + + normal_map + + + + + false + + + + 118 + 57 + 100 + 20 + + + + + 100 + 16777215 + + + - - - - - 45 - 16777215 - - - - - - - - - - - - - 6 - 322 - 520 - 100 - - - - - 520 - 100 - - - - - 520 - 100 - - - - background color - - - diffuse - - - true - - - false - - - + - 0 - 24 - - - - - 16777215 - 24 - - - - - - - - - 16777215 - 24 - - - - B - - - Qt::AlignCenter - - - - - - - - 16777215 + 85 24 - - A - - - Qt::AlignCenter - - - - - - 16777215 - 24 + 85 + 28 - R - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - + render_order - + 0 @@ -533,207 +231,631 @@ - 16777215 - 24 + 100 + 105 - - - - - - - 16777215 - 24 - - - - G - - - Qt::AlignCenter + + Set render order for coplanar polygons. The higher value will be rendered on top of the other coplanar polygons - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - - - + + - 45 + 56 16777215 - + shininess - - - - - - 6 - 434 - 520 - 100 - - - - - 520 - 100 - - - - - 520 - 100 - - - - background color - - - specular - - - true - - - false - - - - + + - 0 + 90 24 - 16777215 - 24 + 100 + 27 - - - + + + - 16777215 - 24 + 520 + 100 - - B - - - Qt::AlignCenter - - - - - - 16777215 - 24 + 520 + 100 - - A - - - Qt::AlignCenter - + + background color + + + diffuse + + + true + + + false + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + A + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + B + + + Qt::AlignCenter + + + + + + + + 45 + 16777215 + + + + + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + G + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + R + + + Qt::AlignCenter + + + + - - - - - 16777215 - 24 - - - - R - - - Qt::AlignCenter - - - - - + + - 0 - 24 + 520 + 100 - 16777215 - 24 + 520 + 100 + + background color + + + specular + + + true + + + false + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + B + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + A + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + R + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + G + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 45 + 16777215 + + + + + + + + - - + + - 0 - 24 + 520 + 100 - 16777215 - 24 - - - - - - - - - 16777215 - 24 + 520 + 100 - - G - - - Qt::AlignCenter - + + background color + + + emissive + + + true + + + false + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + B + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + A + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + R + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + G + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 45 + 16777215 + + + + + + + + - - + + 0 @@ -742,63 +864,17 @@ - 16777215 - 24 - - - - - - - - - 45 - 16777215 + 120 + 25 - + lighting - - - - - - 6 - 544 - 520 - 100 - - - - - 520 - 100 - - - - - 520 - 100 - - - - background color - - - emissive - - - true - - - false - - - - + + 0 @@ -807,312 +883,1091 @@ - 16777215 - 24 - - - - - - - - - 16777215 - 24 + 120 + 25 - B - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - A - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - R - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - + double_sided - - + + - 0 - 24 - - - - - 16777215 - 24 + 470 + 933 - - - - - 16777215 - 24 + 520 + 1100 - - G - - - Qt::AlignCenter - + + pbr + + + true + + + false + + + + + + metal + + + true + + + false + + + + + + albedo_map + + + + + + + false + + + + + + + roughness_map + + + + + + + false + + + + + + + roughness + + + + + + + false + + + + + + + metalness_map + + + + + + + false + + + + + + + metalness + + + + + + + false + + + + 250 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + environment_map + + + + + + + false + + + + + + + ambient_occlusion_map + + + + + + + false + + + + + + + emissive_map + + + + + + + false + + + + + + + + 100 + 140 + + + + + 210 + 140 + + + + normal_map + + + true + + + false + + + + + + + 0 + 24 + + + + + + + + + 50 + 24 + + + + + 75 + 26 + + + + type + + + + + + + + 105 + 24 + + + + + 110 + 27 + + + + + tangent + + + + + object + + + + + + + + + + + + 220 + 75 + + + + + 250 + 140 + + + + light_map + + + true + + + false + + + + + + + 135 + 24 + + + + + 175 + 27 + + + + + + + + + 0 + 24 + + + + uv_set + + + + + + + false + + + + 90 + 24 + + + + + 120 + 27 + + + + + + + + + + + + + + + 400 + 370 + + + + + 450 + 370 + + + + specular + + + true + + + false + + + + + + albedo_map + + + + + + + specular_map + + + + + + + glossiness + + + + + + + false + + + + 250 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + environment_map + + + + + + + ambient_occlusion_map + + + + + + + false + + + + + + + emissive_map + + + + + + + glossiness_map + + + + + + + + 200 + 100 + + + + + 210 + 130 + + + + light_map + + + true + + + false + + + + + + + 100 + 24 + + + + + 170 + 30 + + + + + + + + + 50 + 24 + + + + + 95 + 30 + + + + uv_set + + + + + + + false + + + + 85 + 24 + + + + + + + + + + + + 200 + 94 + + + + + 300 + 130 + + + + normal_map + + + false + + + true + + + false + + + + + + + + + type + + + + + + + + tangent + + + + + object + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + - - + + - 0 - 24 + 520 + 100 - 16777215 - 24 + 520 + 100 - - - - - - - 45 - 16777215 - - - - - + + background color + + + ambient + + + true + + + false + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + B + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + A + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + R + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + G + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 45 + 16777215 + + + + + + + + - - - - 382 - 184 - 57 - 15 - - - - shininess - - - - - - 446 - 180 - 87 - 24 - - - - - 0 - 24 - - - - - - - 116 - 650 - 105 - 24 - - - - - 0 - 24 - - - - double_sided - - - - - - 60 - 52 - 62 - 24 - - - - - 0 - 24 - - - - - - - 446 - 20 - 80 - 24 - - - - - 0 - 24 - - - - browse - - - - - - 326 - 20 - 113 - 24 - - - - - 0 - 24 - - - - - - - 282 - 18 - 37 - 24 - - - - - 0 - 24 - - - - points - - - - - - 18 - 52 - 34 - 24 - - - - - 0 - 24 - - - - width - - - - - - 62 - 18 - 113 - 24 - - - - - 0 - 24 - - - - - - - 16 - 18 - 34 - 24 - - - - - 0 - 24 - - - - name - - - + + + metal_albedo_map_checkBox + toggled(bool) + metal_albedo_map_lineEdit + setEnabled(bool) + + + 140 + 689 + + + 356 + 689 + + + + + metal_roughness_map_checkBox + toggled(bool) + metal_roughness_map_lineEdit + setEnabled(bool) + + + 140 + 728 + + + 356 + 728 + + + + + metal_roughness_checkBox + toggled(bool) + metal_roughness_lineEdit + setEnabled(bool) + + + 140 + 767 + + + 356 + 767 + + + + + metalness_map_checkBox + toggled(bool) + metalness_map_lineEdit + setEnabled(bool) + + + 140 + 806 + + + 356 + 806 + + + + + metalness_checkBox + toggled(bool) + metalness_sp + setEnabled(bool) + + + 140 + 845 + + + 356 + 845 + + + + + metal_environment_map_checkBox + toggled(bool) + metal_environment_map_lineEdit + setEnabled(bool) + + + 140 + 885 + + + 356 + 885 + + + + + metal_ambient_occlusion_map_checkBox + toggled(bool) + metal_ambient_occlusion_map_lineEdit + setEnabled(bool) + + + 140 + 924 + + + 356 + 924 + + + + + metal_emissive_map_checkBox + toggled(bool) + metal_emissive_map_lineEdit + setEnabled(bool) + + + 140 + 963 + + + 356 + 963 + + + + + metal_uv_set_checkBox + toggled(bool) + metal_uv_set_sp + setEnabled(bool) + + + 321 + 1091 + + + 422 + 1091 + + + + + normal_map_checkBox + toggled(bool) + material_normal_map_input + setEnabled(bool) + + + 334 + 89 + + + 440 + 89 + + + + + specular_albedo_map_checkBox + toggled(bool) + specular_albedo_map_lineEdit + setEnabled(bool) + + + 122 + 1200 + + + 338 + 1200 + + + + + specular_map_checkBox + toggled(bool) + specular_map_lineEdit + setEnabled(bool) + + + 122 + 1229 + + + 338 + 1229 + + + + + specular_glossiness_map_checkBox + toggled(bool) + specular_glossiness_map_lineEdit + setEnabled(bool) + + + 122 + 1375 + + + 338 + 1375 + + + + + specular_glossiness_checkBox + toggled(bool) + specular_glossiness_sp + setEnabled(bool) + + + 122 + 1258 + + + 338 + 1258 + + + + + specular_environment_map_checkBox + toggled(bool) + specular_environment_map_lineEdit + setEnabled(bool) + + + 122 + 1288 + + + 338 + 1288 + + + + + specular_ambient_occlusion_map_checkBox + toggled(bool) + specular_ambient_occlusion_map_lineEdit + setEnabled(bool) + + + 155 + 1317 + + + 374 + 1317 + + + + + specular_emissive_map_checkBox + toggled(bool) + specular_emissive_map_lineEdit + setEnabled(bool) + + + 122 + 1346 + + + 338 + 1346 + + + + + specular_uv_set_checkBox + toggled(bool) + specular_uv_set_sp + setEnabled(bool) + + + 110 + 1484 + + + 201 + 1484 + + + + diff --git a/robot_descriptor/forms/surface.ui b/robot_descriptor/forms/surface.ui new file mode 100644 index 0000000..145d935 --- /dev/null +++ b/robot_descriptor/forms/surface.ui @@ -0,0 +1,1717 @@ + + + Form + + + + 0 + 0 + 600 + 810 + + + + + 600 + 0 + + + + + 653 + 16777215 + + + + Form + + + + + + + + + surface + + + + + + bounce + + + true + + + false + + + + + + + 90 + 24 + + + + + 110 + 27 + + + + Bounciness coefficient of restitution, from [0...1], where 0=no bounciness + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + threshold + + + + + + + + 90 + 24 + + + + + 110 + 27 + + + + Bounce capture velocity, below which effective coefficient of restitution is 0 + + + 10000.000000000000000 + + + 1.000000000000000 + + + + + + + restitution_coefficient + + + + + + + + + + true + + + + 0 + 630 + + + + 0 + + + false + + + false + + + false + + + + friction + + + + + + + + + true + + + false + + + + + + + 508 + 16777215 + + + + bullet + + + true + + + false + + + + + + friction + + + + + + + false + + + Coefficient of friction in first friction pyramid direction, + the unitless maximum ratio of force in first friction pyramid + direction to normal force + + + + + + + friction2 + + + + + + + false + + + Coefficient of friction in second friction pyramid direction, + the unitless maximum ratio of force in second friction pyramid + direction to normal force + + + + + + + rolling_friction + + + + + + + false + + + Coefficient of rolling friction + + + + + + + + 500 + 465 + + + + Unit vector specifying first friction pyramid direction in + collision-fixed reference frame + + + fdir1 + + + true + + + false + + + + + + + 27 + 16777215 + + + + x + + + Qt::AlignCenter + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 27 + 16777215 + + + + y + + + Qt::AlignCenter + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 27 + 27 + + + + z + + + Qt::AlignCenter + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + + + + + + + 0 + 205 + + + + + 505 + 220 + + + + ODE + + + true + + + false + + + + + + mu + + + + + + + false + + + Coefficient of friction in first friction pyramid direction, + the unitless maximum ratio of force in first friction pyramid + direction to normal force. + + + + + + + slip1 + + + + + + + false + + + Force dependent slip in first friction pyramid direction, +equivalent to inverse of viscous damping coefficient + with units of m/s/N. + A slip value of 0 is infinitely viscous + + + + + + + mu2 + + + + + + + false + + + Coefficient of friction in second friction pyramid direction, + the unitless maximum ratio of force in second friction pyramid + direction to normal force. + + + + + + + slip2 + + + + + + + false + + + Force dependent slip in second friction pyramid direction, + equivalent to inverse of viscous damping coefficient + with units of m/s/N. + A slip value of 0 is infinitely viscous. + + + + + + + + 500 + 465 + + + + unit vector specifying first friction pyramid direction in + collision-fixed reference frame. + If the friction pyramid model is in use, + and this value is set to a unit vector for one of the + colliding surfaces + + + fdir1 + + + true + + + false + + + + + + + 27 + 16777215 + + + + x + + + Qt::AlignCenter + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 27 + 16777215 + + + + y + + + Qt::AlignCenter + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 27 + 27 + + + + z + + + Qt::AlignCenter + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + + + + + + + 0 + 160 + + + + + 533 + 170 + + + + torsional + + + true + + + false + + + + + + + 0 + 24 + + + + + 70 + 16777215 + + + + coefficient + + + + + + + + 0 + 24 + + + + + 90 + 16777215 + + + + Torsional friction coefficient, unitless maximum ratio of + tangential stress to normal stress. + + + + + + + ode + + + true + + + false + + + + + 24 + 62 + 57 + 15 + + + + slip + + + + + + 95 + 58 + 83 + 23 + + + + + + + + + + 0 + 24 + + + + + 130 + 16777215 + + + + If this flag is true, + torsional friction is calculated using the "patch_radius" parameter. + If this flag is set to false, + "surface_radius" (R) and contact depth (d) + are used to compute the patch radius as sqrt(R*d). + + + use_patch_radius + + + + + + + + 95 + 24 + + + + + 80 + 16777215 + + + + patch_radius + + + + + + + + 0 + 24 + + + + + 90 + 16777215 + + + + Radius of contact patch surface + + + + + + + + 0 + 24 + + + + + 130 + 16777215 + + + + surface_radius + + + + + + + + 0 + 24 + + + + + 90 + 16777215 + + + + Surface radius on the point of contact + + + + + + + + + + + + + + contact + + + + + + + + + true + + + false + + + + + + + 220 + 16777215 + + + + Flag to disable contact force generation, while still allowing collision checks and contact visualization to occur + + + collide_without_contact + + + + + + + + 220 + 16777215 + + + + collide_without_contact_bitmask + + + + + + + false + + + + 50 + 24 + + + + + 120 + 16777215 + + + + Bitmask for collision filtering when collide_without_contact is on + + + + + + + + 120 + 16777215 + + + + collide_bitmask + + + + + + + false + + + + 50 + 24 + + + + + 120 + 16777215 + + + + Bitmask for collision filtering. This will override collide_without_contact. Parsed as 16-bit unsigned integer + + + 65535 + + + + + + + + 0 + 24 + + + + + 150 + 16777215 + + + + category_bitmask + + + + + + + false + + + + 50 + 24 + + + + + 120 + 16777215 + + + + Bitmask for category of collision filtering. +Collision happens if ((category1 & collision2) | (category2 & collision1)) is not zero. +If not specified, the category_bitmask should be interpreted as being the same as collide_bitmask. +Parsed as 16-bit unsigned integer + + + 65535 + + + + + + + + 120 + 16777215 + + + + poissons_ratio + + + + + + + false + + + + 50 + 24 + + + + + 120 + 16777215 + + + + Poisson's ratio is the unitless ratio between transverse and axial strain. + This value must lie between (-1, 0.5). Defaults to 0.3 for typical steel. + Note typical silicone elastomers have Poisson's ratio near 0.49 ~ 0.50 + + + + + + + + 120 + 16777215 + + + + elastic_modulus + + + + + + + false + + + + 50 + 24 + + + + + 120 + 16777215 + + + + Young's Modulus in SI derived unit Pascal. + Defaults to -1. If value is less or equal to zero, + contact using elastic modulus (with Poisson's Ratio) is disabled. + + + + + + + ode + + + true + + + false + + + + + + soft_cfm + + + + + + + false + + + Soft constraint force mixing + + + + + + + kd + + + + + + + false + + + dynamically "damping"-equivalent coefficient for contact joints + + + + + + + soft_erp + + + + + + + false + + + Soft error reduction parameter + + + + + + + max_vel + + + + + + + false + + + maximum contact correction velocity truncation term. + + + + + + + kp + + + + + + + false + + + dynamically "stiffness"-equivalent coefficient for contact joints + + + 10000000000000.000000000000000 + + + + + + + min_depth + + + + + + + false + + + minimum allowable depth before contact correction impulse is applied + + + + + + + + + + + 500 + 155 + + + + bullet + + + true + + + false + + + + + + soft_cfm + + + + + + + false + + + Soft constraint force mixing + + + + + + + soft_erp + + + + + + + false + + + see ode + + + + + + + kp + + + + + + + split_impulse_penetration_threshold + + + + + + + false + + + see ode + + + 10000000000000.000000000000000 + + + + + + + imilar to ODE's max_vel implementation + + + + + + + kd + + + + + + + false + + + see ode + + + + + + + split_impulse + + + + + + + + + + + + + + soft_contact + + + + + + soft_contact + + + true + + + + + + bone_attachment + + + + + + + This is variable k_v in the soft contacts paper. Its unit is N/m + + + N/m + + + 1000.000000000000000 + + + + + + + stiffness + + + + + + + This is variable k_e in the soft contacts paper + + + N/m + + + 1000.000000000000000 + + + + + + + damping + + + + + + + Viscous damping of point velocity in body frame + + + N/m/s + + + 1000.000000000000000 + + + + + + + flesh_mass_fraction + + + + + + + Fraction of mass to be distributed among deformable nodes + + + + + + + + + + Qt::Horizontal + + + + 248 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 448 + + + + + + + + + + + + + + + + + + + + surface_ode_mu_cb + toggled(bool) + surface_ode_mu_sp + setEnabled(bool) + + + 121 + 425 + + + 240 + 425 + + + + + surface_ode_mu2_cb + toggled(bool) + surface_ode_mu2_sp + setEnabled(bool) + + + 121 + 455 + + + 240 + 455 + + + + + surface_ode_slip1_cb + toggled(bool) + surface_ode_slip1_sp + setEnabled(bool) + + + 359 + 425 + + + 478 + 425 + + + + + surface_ode_slip2_cb + toggled(bool) + surface_ode_slip2_sp + setEnabled(bool) + + + 359 + 455 + + + 478 + 455 + + + + + surface_bullet_friction_cb + toggled(bool) + surface_bullet_friction_sp + setEnabled(bool) + + + 98 + 636 + + + 169 + 636 + + + + + surface_bullet_friction2_cb + toggled(bool) + surface_bullet_friction2_sp + setEnabled(bool) + + + 244 + 636 + + + 318 + 636 + + + + + surface_bullet_rolling_friction_cb + toggled(bool) + surface_bullet_rolling_friction_sp + setEnabled(bool) + + + 411 + 636 + + + 503 + 636 + + + + + contact_collide_without_contact_bitmask_cb + toggled(bool) + contact_collide_without_contact_bitmask_sp + setEnabled(bool) + + + 162 + 253 + + + 434 + 253 + + + + + contact_poissons_ratio_cb + toggled(bool) + contact_poissons_ratio_sp + setEnabled(bool) + + + 112 + 343 + + + 434 + 343 + + + + + contact_collide_bitmask_cb + toggled(bool) + contact_collide_bitmask_sp + setEnabled(bool) + + + 112 + 283 + + + 434 + 283 + + + + + contact_category_bitmask_cb + toggled(bool) + contact_category_bitmask_sp + setEnabled(bool) + + + 127 + 313 + + + 434 + 313 + + + + + contact_elastic_modulus_cb + toggled(bool) + contact_elastic_modulus_sp + setEnabled(bool) + + + 112 + 373 + + + 434 + 373 + + + + + contact_ode_soft_cfm_cb + toggled(bool) + contact_ode_soft_cfm_sp + setEnabled(bool) + + + 115 + 446 + + + 245 + 446 + + + + + contact_ode_soft_erp_cb + toggled(bool) + contact_ode_soft_erp_sp + setEnabled(bool) + + + 115 + 489 + + + 245 + 489 + + + + + contact_ode_kp_cb + toggled(bool) + contact_ode_kp_sp + setEnabled(bool) + + + 115 + 532 + + + 245 + 532 + + + + + contact_ode_kd_cb + toggled(bool) + contact_ode_kd_sp + setEnabled(bool) + + + 375 + 446 + + + 483 + 446 + + + + + contact_ode_max_vel_cb + toggled(bool) + contact_ode_max_vel_sp + setEnabled(bool) + + + 375 + 489 + + + 483 + 489 + + + + + contact_ode_min_depth_cb + toggled(bool) + contact_ode_min_depth_sp + setEnabled(bool) + + + 375 + 532 + + + 483 + 532 + + + + + contact_bullet_soft_cfm_cb + toggled(bool) + contact_bullet_soft_cfm_sp + setEnabled(bool) + + + 102 + 623 + + + 219 + 623 + + + + + contact_bullet_kp_cb + toggled(bool) + contact_bullet_kp_sp + setEnabled(bool) + + + 102 + 691 + + + 219 + 691 + + + + + contact_bullet_soft_erp_cb + toggled(bool) + contact_bullet_soft_erp_sp + setEnabled(bool) + + + 102 + 657 + + + 219 + 657 + + + + + contact_bullet_kd_cb + toggled(bool) + contact_bullet_kd_sp + setEnabled(bool) + + + 350 + 623 + + + 474 + 623 + + + + + diff --git a/robot_descriptor/forms/visual.ui b/robot_descriptor/forms/visual.ui new file mode 100644 index 0000000..36d67fa --- /dev/null +++ b/robot_descriptor/forms/visual.ui @@ -0,0 +1,153 @@ + + + Form + + + + 0 + 0 + 730 + 700 + + + + + 695 + 700 + + + + Form + + + + + + + + + laser_retro + + + + + + + false + + + + + + + transparency + + + + + + + false + + + + + + + false + + + visibility_flags + + + + + + + false + + + 900000000 + + + QAbstractSpinBox::DefaultStepType + + + + + + + cast_shadows + + + + + + + + 660 + 600 + + + + + 16777215 + 607 + + + + true + + + + + 0 + 0 + 692 + 605 + + + + + + + + + + + + + + visual_laser_retro_cb + toggled(bool) + visual_laser_retro_sp + setEnabled(bool) + + + 73 + 29 + + + 189 + 29 + + + + + visual_transparency_cb + toggled(bool) + visual_transparency_sp + setEnabled(bool) + + + 306 + 29 + + + 423 + 29 + + + + + diff --git a/robot_descriptor/forms/world.ui b/robot_descriptor/forms/world.ui index f81e4fe..74c7644 100644 --- a/robot_descriptor/forms/world.ui +++ b/robot_descriptor/forms/world.ui @@ -65,8 +65,8 @@ 12 14 - 589 - 655 + 587 + 648 @@ -1575,8 +1575,8 @@ to zero if you want the min COR always to be used 10 10 - 541 - 333 + 543 + 421 @@ -1588,323 +1588,374 @@ to zero if you want the min COR always to be used false - - - - 170 - 30 - 119 - 23 - - - - name of planetary surface model, used to determine the surface altitude + + + + + + 95 + 24 + + + + + 100 + 24 + + + + surface_model + + + + + + + + 117 + 21 + + + + + 120 + 24 + + + + name of planetary surface model, used to determine the surface altitude at a given latitude and longitude. The default is an ellipsoid model of the earth based on the WGS-84 standard. It is used in Gazebo's GPS sensor implementation. - - - false - - - - EARTH_WGS84 - + + + false + + + + EARTH_WGS84 + + + - - - - - 20 - 40 - 88 - 15 - - - - surface_model - - - - - - 20 - 70 - 147 - 15 - - - - world_frame_orientation - - - - - - 170 - 60 - 153 - 23 - - - - This field identifies how Gazebo world frame is aligned in Geographical + + + + + 155 + 24 + + + + world_frame_orientation + + + + + + + + 151 + 21 + + + + + 155 + 24 + + + + This field identifies how Gazebo world frame is aligned in Geographical sense. The final Gazebo world frame orientation is obtained by rotating a frame aligned with following notation by the field heading_deg. Options are: - - - false - - - - ENU (East-North-Up) - + + + false + + + + ENU (East-North-Up) + + + - - - - - 20 - 100 - 75 - 15 - - - - latitude_deg - - - - - - 170 - 96 - 81 - 24 - - - - Geodetic latitude at origin of gazebo reference frame, specified + + + + + 85 + 24 + + + + latitude_deg + + + + + + + + 88 + 24 + + + + + 90 + 24 + + + + Geodetic latitude at origin of gazebo reference frame, specified in units of degrees. - - - - - - ° - - - 4 - - - -90.000000000000000 - - - 90.000000000000000 - - - - - - 20 - 130 - 86 - 15 - - - - longitude_deg - - - - - - 168 - 126 - 81 - 24 - - - - Longitude at origin of gazebo reference frame, specified in units + + + + + + ° + + + 4 + + + -90.000000000000000 + + + 90.000000000000000 + + + + + + + + 95 + 24 + + + + longitude_deg + + + + + + + + 0 + 24 + + + + + 100 + 24 + + + + Longitude at origin of gazebo reference frame, specified in units of degrees - - - ° - - - 4 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - 20 - 158 - 57 - 15 - - - - elevation - - - - - - 168 - 154 - 85 - 24 - - - - Elevation of origin of gazebo reference frame, specified in meters - - - m - - - 4 - - - 10000.000000000000000 - - - - - - 340 - 30 - 78 - 15 - - - - heading_deg - - - - - - 428 - 26 - 89 - 24 - - - - Heading offset of gazebo reference frame, measured as angle between + + + ° + + + 4 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + 65 + 24 + + + + elevation + + + + + + + + 112 + 24 + + + + + 120 + 24 + + + + Elevation of origin of gazebo reference frame, specified in meters + + + m + + + 4 + + + 10000.000000000000000 + + + + + + + + 85 + 24 + + + + heading_deg + + + + + + + + 80 + 24 + + + + + 85 + 24 + + + + Heading offset of gazebo reference frame, measured as angle between Gazebo world frame and the world_frame_orientation type. The direction of rotation follows the right-hand rule, so a positive angle indicates clockwise rotation (from east to north) when viewed from top-down. Note that this is not consistent with compass heading convention. The angle is specified in degrees. - - - ° - - - -360.000000000000000 - - - 360.000000000000000 - - - - - - 16 - 260 - 161 - 67 - - - - surface_axis_polar - - - true - - - false - - - - - 8 - 26 - 109 - 24 - - - - Polar axis of a custom surface type, specified in meters. - This is only required for custom surfaces - - - m - - - 4 - - - 10000.000000000000000 - - - - - - - 14 - 182 - 165 - 69 - - - - surface_axis_equatorial - - - true - - - false - - - - - 4 - 28 - 104 - 24 - - - - Equatorial axis of a custom surface type, specified in meters. + + + ° + + + -360.000000000000000 + + + 360.000000000000000 + + + + + + + + 175 + 65 + + + + + 180 + 70 + + + + surface_axis_equatorial + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + false + + + + + + Equatorial axis of a custom surface type, specified in meters. This is only required for custom surfaces. - - - m - - - 4 - - - 1000.000000000000000 - - - - - + + + m + + + 4 + + + 1000.000000000000000 + + + + + + + + + + + 159 + 61 + + + + + 170 + 70 + + + + surface_axis_polar + + + true + + + false + + + + + + Polar axis of a custom surface type, specified in meters. + This is only required for custom surfaces + + + m + + + 4 + + + 10000.000000000000000 + + + + + + + + + 6 @@ -1923,13 +1974,10 @@ of degrees light - - - - - 16777215 - 100 - + + + + Reset @@ -1963,67 +2011,11 @@ of degrees 0 0 - 551 + 549 771 - - - - name - - - - - - - - 0 - 23 - - - - - - - - type - - - - - - - - 0 - 23 - - - - - point - - - - - spot - - - - - directional - - - - - - - - intensity - - - @@ -2040,219 +2032,205 @@ of degrees - - - - - 0 - 21 - - - - cast_shadows - - - - - - - - 0 - 21 - - - - visualize - - - true - - - - - - - - 0 - 21 - - + + - light_on - - - true + intensity - - + + - 489 - 98 - - - - - 533 - 16777215 + 505 + 145 - Diffuse + pose - - - - - - 0 - 25 - + + + + + x - - - 64 - 16777215 - + + Qt::AlignCenter - - 1.000000000000000 + + + + + + y - - 0.100000000000000 + + Qt::AlignCenter - - 1.000000000000000 + + + + + + z + + + Qt::AlignCenter - + 0 25 - - - 64 - 16777215 - - - - 1.000000000000000 + + 4 - - 0.100000000000000 + + -100.000000000000000 - - 1.000000000000000 + + 1000.000000000000000 - - + + 0 25 - + + 4 + + + -100.000000000000000 + + + 1000.000000000000000 + + + + + + - 64 - 16777215 + 0 + 25 - - 1.000000000000000 + + 4 - - 0.100000000000000 + + -100.000000000000000 - - 1.000000000000000 + + 1000.000000000000000 - - - - A + + + + roll Qt::AlignCenter - - + + - R + pitch Qt::AlignCenter - - + + + + yaw + + + Qt::AlignCenter + + + + + 0 25 - - - 64 - 16777215 - + + rad - - 1.000000000000000 + + 4 - - 0.100000000000000 + + -6.283200000000000 - - 1.000000000000000 + + 6.283200000000000 - - - - G + + + + + 0 + 25 + - - Qt::AlignCenter + + rad - - - - - - B + + 4 - - Qt::AlignCenter + + -6.283200000000000 + + + 6.283200000000000 - - - + + + - 45 - 16777215 + 0 + 25 - - + + rad + + + 4 + + + -6.283200000000000 + + + 6.283200000000000 @@ -2469,136 +2447,20 @@ of degrees - - + + 0 - 75 - - - - - 534 - 16777215 - - - - attenuation - - - - - - constant - - - - - - - - 64 - 25 - - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - Qt::Horizontal - - - - quadratic - - - - - - 64 - 25 - - - - 0.100000000000000 - - - - - - - - linear - - - - - - - - 64 - 25 - - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - - 64 - 25 - - - - 100000.000000000000000 - - - 0.100000000000000 - - - 10.000000000000000 - - - - - - - range - - - - - - - - - - - 505 - 145 + 94 - pose + direction - + - + x @@ -2608,7 +2470,7 @@ of degrees - + y @@ -2618,7 +2480,7 @@ of degrees - + z @@ -2628,261 +2490,436 @@ of degrees - + 0 25 - - 4 - -100.000000000000000 - - 1000.000000000000000 - - + 0 25 - - 4 - -100.000000000000000 - - 1000.000000000000000 - - + 0 25 - - 4 - -100.000000000000000 - - 1000.000000000000000 + + -1.000000000000000 - - - - roll - - - Qt::AlignCenter - - - - - - - pitch - - - Qt::AlignCenter - - - - - - - yaw - - - Qt::AlignCenter - - - - - + + + + + + + + 0 + 21 + + + + cast_shadows + + + + + + + + 489 + 98 + + + + + 533 + 16777215 + + + + Diffuse + + + + 0 25 - - rad + + + 64 + 16777215 + - - 4 + + 1.000000000000000 - - -6.283200000000000 + + 0.100000000000000 - - 6.283200000000000 + + 1.000000000000000 - - + + 0 25 - - rad + + + 64 + 16777215 + - - 4 + + 1.000000000000000 - - -6.283200000000000 + + 0.100000000000000 - - 6.283200000000000 + + 1.000000000000000 - - + + 0 25 - - rad - - - 4 - - - -6.283200000000000 + + + 64 + 16777215 + - 6.283200000000000 + 1.000000000000000 - - - - - - - - - - 0 - 94 - - - - direction - - - - - - x + + 0.100000000000000 - - Qt::AlignCenter + + 1.000000000000000 - - + + - y + A Qt::AlignCenter - - + + - z + R Qt::AlignCenter - - + + 0 25 - - -100.000000000000000 + + + 64 + 16777215 + + + + 1.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 - - - - - 0 - 25 - + + + + G - - -100.000000000000000 + + Qt::AlignCenter - - - + + + + B + + + Qt::AlignCenter + + + + + + - 0 - 25 + 45 + 16777215 - - -100.000000000000000 - - - -1.000000000000000 + + - - - + + + + + 0 + 21 + + + + visualize + + true + + + + 0 - 100 + 75 - - spot + + + 534 + 16777215 + + + + attenuation + + + + + + constant + + + + + + + + 64 + 25 + + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + Qt::Horizontal + + + + + 65 + 24 + + + + quadratic + + + + + + 64 + 25 + + + + 0.100000000000000 + + + + + + + + linear + + + + + + + + 64 + 25 + + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + + 64 + 25 + + + + 100000.000000000000000 + + + 0.100000000000000 + + + 10.000000000000000 + + + + + + + range + + + + + + + + + + name + + + + + + + + 0 + 23 + + + + + point + + + + + spot + + + + + directional + + + + + + + + + 0 + 21 + + + + light_on + + + true + + + + + + + true + + + + 0 + 100 + + + + spot @@ -2960,14 +2997,34 @@ of degrees + + + + + 0 + 23 + + + + + + + + type + + + - - - - Reset + + + + + 16777215 + 100 + @@ -3397,1535 +3454,52 @@ of degrees true - - - - - cubemap_uri - - - - - - - time - - - - - - - 24.000000000000000 - - - - - - - - 0 - 23 - - - - - - - - sunset - - - - - - - clouds - - - true - - - - - - mean_size - - - - - - - humidity - - - - - - - direction - - - - - - - Density of clouds - - - 4 - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 100 - - - - - - - ambient - - - - - - - 16777215 - 24 - - - - R - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - B - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 24 - - - - G - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - A - - - Qt::AlignCenter - - - - - - - - 45 - 16777215 - - - - - - - - - - - - - - Direction of the cloud movement - - - 4 - - - 3.145600000000000 - - - 0.100000000000000 - - - - - - - speed - - - - - - - - 70 - 16777215 - - - - Speed of the clouds - - - 4 - - - - - - - - 60 - 24 - - - - 4 - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - - - - 80 - 16777215 - - - - 24.000000000000000 - - - - - - - sunrise - - - - - - - 24.000000000000000 - - - - - - - - - - - 0 - 24 - - - - - 150 - 16777215 - - - - shadows - - - - - - - - 0 - 24 - - - - - 150 - 16777215 - - - - grid - - - - - - - - 160 - 24 - - - - - 150 - 16777215 - - - - origin_visual - - - - - - - - 520 - 203 - - - - - 530 - 16777215 - - - - fog - - - true - - - - - - type - - - - - - - - 0 - 24 - - - - - 100 - 25 - - - - - none - - - - - constant - - - - - linear - - - - - quadratic - - - - - - - - - 450 - 100 - - - - - 16777215 - 100 - - - - fog color - - - color - - - - - - - 16777215 - 24 - - - - B - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - A - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 24 - - - - G - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 24 - - - - R - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 46 - 16777215 - - - - - - - - - - - - - - density - - - - - - - Density of fog - - - - - - - end - - - - - - - Distance to end of fog - - - 1000.000000000000000 - - - - - - - Distance to start of fog - - - - - - - start - - - - - - - - - - - - - 8 - 586 - 80 - 23 - - - - Reset - - - - - - 456 - 586 - 110 - 21 - - - - enable_scene - - - - - - road - - - - - 432 - 592 - 105 - 21 - - - - - 105 - 0 - - - - Enable_road - - - - - - 10 - 596 - 80 - 23 - - - - Reset - - - - - - 10 - 12 - 569 - 571 - - - - true - - - - - 0 - 0 - 553 - 672 - - - - - - - Qt::Horizontal - - - - - 0 - 24 - - - - name - - - - - - 0 - 24 - - - - - - - - - - 500 - 624 - - - - - 570 - 630 - - - - material - - - true - - - false - - - - - - - 240 - 89 - - - - - 240 - 16777215 - - - - script - - - true - - - false - - - - - 18 - 28 - 16 - 15 - - - - uri - - - - - - 52 - 24 - 153 - 23 - - - - - 160 - 16777215 - - - - - - - 12 - 56 - 34 - 15 - - - - name - - - - - - 52 - 52 - 113 - 23 - - - - - 115 - 16777215 - - - - - - - - - - 240 - 95 - - - - - 240 - 16777215 - - - - shader - - - true - - - false - - - - - 12 - 30 - 57 - 16 - - - - type - - - - - - 82 - 26 - 100 - 21 - - - - - 100 - 16777215 - - - - - pixel - - - - - vertex - - - - - normal_map_object_space - - - - - normal_map_tangent_space - - - - - - - 12 - 57 - 100 - 20 - - - - normal_map - - - - - - 118 - 57 - 100 - 20 - - - - - 100 - 16777215 - - - - - - - - - Qt::Horizontal - - - - - 85 - 24 - - - - - 85 - 28 - - - - render_order - - - - - - 0 - 24 - - - - - 100 - 16777215 - - - - Set render order for coplanar polygons. The higher value will be rendered on top of the other coplanar polygons - - - - - - - - Qt::Horizontal - - - - - 56 - 16777215 - - - - shininess - - - - - - 0 - 24 - - - - - 100 - 27 - - - - - - - - - - 520 - 100 - - - - - 520 - 100 - - - - background color - - - ambient - - - true - - - false - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 24 - - - - B - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - A - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - R - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 24 - - - - G - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 45 - 16777215 - - - - - - - - - - - - - - - 520 - 100 - - - - - 520 - 100 - - - - background color - - - diffuse - - - true - - - false - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 24 - - - - B - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - A - - - Qt::AlignCenter - - - - - - - - 16777215 - 24 - - - - R - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 16777215 - 24 - - - - G - - - Qt::AlignCenter - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 - - - - - - - - 45 - 16777215 - - - - - - - - + + false + + + + + + cubemap_uri + - - - - - 520 - 100 - + + + + time - + + + + + + 24.000000000000000 + + + + + + - 520 - 100 + 0 + 23 - - background color + + + + + + sunset + + + + - specular + clouds true @@ -4933,150 +3507,276 @@ of degrees false - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 + + + + + mean_size - - - - - 16777215 - 24 - - + + - B - - - Qt::AlignCenter + humidity - - - - 16777215 - 24 - - + - A + direction - - Qt::AlignCenter + + + + + + Density of clouds + + + 4 + + + 1.000000000000000 + + + 0.100000000000000 - - + + 16777215 - 24 + 100 - - R + + - - Qt::AlignCenter + + ambient + + + + + + 16777215 + 24 + + + + R + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + B + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 1.000000000000000 + + + 0.100000000000000 + + + + + + + + 16777215 + 24 + + + + G + + + Qt::AlignCenter + + + + + + + + 16777215 + 24 + + + + A + + + Qt::AlignCenter + + + + + + + + 45 + 16777215 + + + + + + + + - - - - - 0 - 24 - + + + + Direction of the cloud movement - - - 16777215 - 24 - + + 4 - 1.000000000000000 + 3.145600000000000 0.100000000000000 - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - 1.000000000000000 - - - 0.100000000000000 + + + + speed - + - 16777215 - 24 + 70 + 16777215 - - G + + Speed of the clouds - - Qt::AlignCenter + + 4 - - + + - 0 + 60 24 - - - 16777215 - 24 - + + 4 1.000000000000000 @@ -5086,73 +3786,202 @@ of degrees - - - - - 45 - 16777215 - - - - - - - - - + + + + + 80 + 16777215 + + + + 24.000000000000000 + + + + + + + sunrise + + + + + + + 24.000000000000000 + + + + + + + + + + + 0 + 24 + + + + + 150 + 16777215 + + + + shadows + + + + + + + + 0 + 24 + + + + + 150 + 16777215 + + + + grid + + + + + + + + 160 + 24 + + + + + 150 + 16777215 + + + + origin_visual + + + + + + + + 520 + 203 + + + + + 530 + 16777215 + + + + fog + + + true + + + false + + + + + + type + + + + + + + + 0 + 24 + + + + + 100 + 25 + + + + + none + + + + + constant + + + + + linear + + + + + quadratic + + + + + + - 520 + 450 100 - 520 + 16777215 100 - background color + fog color - emissive - - - true - - - false + color - - - - - - 0 - 24 - - + + + 16777215 24 - - 1.000000000000000 + + B - - 0.100000000000000 + + Qt::AlignCenter - - + + 16777215 @@ -5160,31 +3989,37 @@ of degrees - B + A Qt::AlignCenter - - + + + + + 0 + 24 + + 16777215 24 - - A + + 1.000000000000000 - - Qt::AlignCenter + + 0.100000000000000 - - + + 16777215 @@ -5192,7 +4027,7 @@ of degrees - R + G Qt::AlignCenter @@ -5200,7 +4035,7 @@ of degrees - + 0 @@ -5222,7 +4057,7 @@ of degrees - + 0 @@ -5243,24 +4078,8 @@ of degrees - - - - - 16777215 - 24 - - - - G - - - Qt::AlignCenter - - - - + 0 @@ -5281,11 +4100,33 @@ of degrees + + + + + 16777215 + 24 + + + + R + + + Qt::AlignCenter + + + - + + + + 0 + 0 + + - 45 + 46 16777215 @@ -5297,51 +4138,222 @@ of degrees - - - - - 0 - 24 - + + + + density + + + + + + + Density of fog + + + + + + + end + + + + + + + Distance to end of fog + + + 1000.000000000000000 + + + + + + + Distance to start of fog + + + + - lighting + start - - - - Qt::Horizontal - - - - - 0 - 24 - - - - width - - - - - - 0 - 24 - - - - - + + + + 8 + 586 + 80 + 23 + + + + Reset + + + + + + 456 + 586 + 110 + 21 + + + + enable_scene + + + + + + road + + + + + + Qt::Horizontal + + + + + 50 + 24 + + + + + 55 + 27 + + + + name + + + + + + 100 + 16777215 + + + + + + + + + Qt::Horizontal + + + + + 50 + 24 + + + + + 55 + 25 + + + + width + + + + + + 60 + 24 + + + + + 100 + 25 + + + + + + + + + + 565 + 540 + + + + true + + + + + 0 + 0 + 563 + 540 + + + + + + + + + + 100 + 16777215 + + + + Reset + + + + + + + + 105 + 0 + + + + + 100 + 16777215 + + + + Enable_road + + + + + + + include_material_info + + + + diff --git a/robot_descriptor/icons/link16.png b/robot_descriptor/icons/link16.png new file mode 100644 index 0000000..b1c7113 Binary files /dev/null and b/robot_descriptor/icons/link16.png differ diff --git a/robot_descriptor/icons/link24.png b/robot_descriptor/icons/link24.png new file mode 100644 index 0000000..77ecc24 Binary files /dev/null and b/robot_descriptor/icons/link24.png differ diff --git a/robot_descriptor/icons/link32.png b/robot_descriptor/icons/link32.png new file mode 100644 index 0000000..42a4bbd Binary files /dev/null and b/robot_descriptor/icons/link32.png differ diff --git a/robot_descriptor/icons/ref16.png b/robot_descriptor/icons/ref16.png new file mode 100644 index 0000000..e1a9c47 Binary files /dev/null and b/robot_descriptor/icons/ref16.png differ diff --git a/robot_descriptor/icons/ref24.png b/robot_descriptor/icons/ref24.png new file mode 100644 index 0000000..a4a3599 Binary files /dev/null and b/robot_descriptor/icons/ref24.png differ diff --git a/robot_descriptor/icons/ref32.png b/robot_descriptor/icons/ref32.png new file mode 100644 index 0000000..c00f921 Binary files /dev/null and b/robot_descriptor/icons/ref32.png differ diff --git a/robot_descriptor/initialize.py b/robot_descriptor/initialize.py index d7400fe..8001fe5 100644 --- a/robot_descriptor/initialize.py +++ b/robot_descriptor/initialize.py @@ -6,7 +6,7 @@ #import Spreadsheet import xml.etree.ElementTree as ET -from .RD_parser import initialize_element_tree +from .RD_utils import initialize_element_tree #directory to initilize icon __dirname__ = os.path.join(FreeCAD.getUserAppDataDir(), "Mod", "RobotDescriptor")+"/robot_descriptor/icons/initialize.svg" #class to store the selected properties diff --git a/robot_descriptor/model_editor.py b/robot_descriptor/model_editor.py new file mode 100644 index 0000000..d963118 --- /dev/null +++ b/robot_descriptor/model_editor.py @@ -0,0 +1,270 @@ +from typing import Any +import FreeCAD +import FreeCADGui +import robot_descriptor.common as common +import os +from PySide2 import QtGui +import copy +from .RD_utils import initialize_element_tree + +import xml.etree.ElementTree as ET + +from .RD_utils import parse_asm4_model +from PySide2.QtGui import QStandardItemModel,QStandardItem +from PySide2.QtWidgets import QTreeView,QDialog,QSplitter,QGridLayout,QTabWidget,QHBoxLayout,QWidget +from PySide2.QtCore import QSize, Qt,QModelIndex,QItemSelectionModel,Signal +from .sdf_elements import link +from .sdf_elements import visual +from .sdf_elements import collision + +link_img=QtGui.QImage(os.path.join(common.ICON_PATH,"link24.png")) +ref_img=QtGui.QImage(os.path.join(common.ICON_PATH,"ref24.png")) + + +#start standard item +class ModelItem(QStandardItem): + def __init__(self,model_editor_cls,text,type='link'): + super().__init__() + # data to describe the model + + #types ref,link ... . + self.text=text + self.type=type + #set the text to be displayed + self.setText(text) + self.setEditable(False) + self.model_cls=model_editor_cls + + # self.Model_editor_ui=self.model_cls.Model_editor_ui + + #Tasks + # 1. Implement function to + # i. calculate inertia and write the info to the inertial element ,this might be + # implemented in the inertial class + # ii. extract maerial data e.g color of link... , and write to material element + # + # 2. add user roles to get element data after disabled ui icons have been removed + # so that calling the on the item with the role will return the element after appending them as required + # 3. add slot that can be triggered when user breaks reference so that an element of type reference can + # create its own links and not refer to parent ref item , also another to create links to a parent item + # and one to update ui when to item is selected in the tree view + #4. set tooltip for tree view items , i.e references should give a clue of the parent + #5. right click menu will be responsible for creating and breaking links and jumping to the the parent for references + + #linked + if self.type !='ref': + self.init_elements() + + def init_elements(self): + self.collision_element=initialize_element_tree.convdict_2_tree('collision.sdf').get_element + self._link_element=initialize_element_tree.convdict_2_tree('link.sdf').get_element + self._inertial_element=initialize_element_tree.convdict_2_tree("inertial.sdf").get_element + self.surface_element=initialize_element_tree.convdict_2_tree("surface.sdf").get_element + self._visual_element=initialize_element_tree.convdict_2_tree("visual.sdf").get_element + self._material_element=initialize_element_tree.convdict_2_tree('material.sdf').get_element + + + def create_ref(self,item): + + self.collision_element=item.collision_element + self._link_element=item._link_element + self._inertial_element=item._inertial_element + self.surface_element=item.surface_element + self._visual_element=item._visual_element + self._material_element=item._material_element + self.type='ref' + self.emitDataChanged() + + def break_ref(self): + self.init_elements() + self.type='link' + self.emitDataChanged() + + def selected(self): + #this will called when an item is clicked + #update elements + self.model_cls._link.update_elements(self) + self.model_cls._visual.update_elements(self) + self.model_cls._collision.update_elements(self) + + + def data(self, role: int = ...) -> Any: + if role==Qt.DisplayRole: + return self.text + + if role==Qt.DecorationRole: + if self.type=='link': + return link_img + elif self.type=='ref': + return ref_img + else: + return + + +#end standard Item +#============================================== + + +#model editor +class ModelEditor(QDialog): + + + def __init__(self,elem_struct): + # find all objects of type 'App::Link' + #doc=FreeCAD.ActiveDocument + super(ModelEditor,self).__init__() + + self._elem_struct=elem_struct + self.links_hierarchy=parse_asm4_model.read_assembly() + if self.links_hierarchy is None: + return + # self.ModelEditorUi=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'model_editor.ui')) + + #subelements + self.current_elems=[] + #dictionary of all links and their associated elements + #{link name: [link,collison,visual], ...} + self.elems={} + #used for creating refernces for item of type ref + self.referenced_elems={} + #ui's + self.collision_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'collision.ui')) + self.link_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'link.ui')) + self.visual_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'visual.ui')) + #end ui's + #elements + self._link=link.link(self.link_ui) + self._visual=visual.visual(self.visual_ui) + self._collision=collision.collison(self.collision_ui) + #end elements + + self.setUpUI() + + #create model + self.link_model=QStandardItemModel() + self.link_model.setColumnCount(1) + self.root_node=self.link_model.invisibleRootItem() + self.model_tree_config(self.links_hierarchy["children"],self.root_node) + + #add callback + self.config() + + # start header related + self.link_model.setHorizontalHeaderLabels(["Model Tree"]) + #set the tree to resize automatically based on the display requirements + #end header related + + #set view model + self.view.setModel(self.link_model) + #select the first item + mdl_idx0=self.link_model.index(0,0,self.view.rootIndex()) + self.view.selectionModel().select(mdl_idx0,QItemSelectionModel.Select) + #display dialog + self.exec_() +#end __init__() + + + def sizeHint(self) -> QSize: + return QSize(1030,764) + + def setUpUI(self): + self.setWindowTitle("ModelEditor") + #splitter + self.splitter=QSplitter(self) + self.splitter.setOrientation(Qt.Horizontal) + #create the treeview + self.view=QTreeView(self.splitter) + self.view.setHeaderHidden(False) + self.view.setSelectionMode(self.view.SingleSelection) + #set layout of the main dialog + grid=QGridLayout() + self.setLayout(grid) + grid.addWidget(self.splitter) + #create the tab widget + tab=QTabWidget(self.splitter) + tab.addTab(self.link_ui,"link") + tab.addTab(self.collision_ui,"collision") + tab.addTab(self.visual_ui,"visual") + + self.splitter.addWidget(self.view) + self.splitter.addWidget(tab) + + + + def config(self): + self.view.clicked[QModelIndex].connect(self.on_tree_item) + + + def on_tree_item(self,index): + item = self.link_model.itemFromIndex(index) + # label=item.data(Qt.DisplayRole) + item.selected() + + + def model_tree_config(self,link_str,std_itm): + ref_links=[] + #create the tree view structure + def setup(link_hierarchy,item): + #iterate throuhg all children create items and the to tree + #seee parse_asm4_model.py + for child in link_hierarchy: + name=child["name"] + row=ModelItem(self,child["name"],child['type']) + item.appendRow(row) + #make reference to the index of referenced link + #This assumes the link already exists in the referenced_elems dictionary + if child['type']=='ref': + # row.ref_idx=self.referenced_elems[child["ref_label"]] + # #refer to the data in the refered link + # #since the links are similar + # #this can be updated by right clicking on the tree element and clicking break reference + # self.elems[child['name']]=self.elems[child["ref_label"]] + + #just update the ref_links since the link might not be defined yet + ref_links.append([row,child["ref_label"],name]) + #store index to referred link + elif child['type']=='link': + #add to referenced elements + self.referenced_elems[child['name']]=row + + else: + pass + #deb + #### + #recursion + setup(child["children"],row) + return + setup(link_str,std_itm) + #add ref_link related data + for item,ref_label,name in ref_links: + # item.ref_idx=self.referenced_elems[ref_label] + item.create_ref(self.referenced_elems[ref_label]) + +#+=============================== +#start command +#================================ +class Model_properties(): + """My new command""" + + def GetResources(self): + return {"Pixmap" : os.path.join(common.ICON_PATH,"edit.svg"),# the name of a svg file available in the resources + "Accel" : "Shift+E", # a default shortcut (optional) + "MenuText": "Model Edits", + "ToolTip" : "Edit link and joint properties"} + + def Activated(self): + if hasattr(FreeCAD.ActiveDocument,"Assembly") or hasattr(FreeCAD.ActiveDocument,"Model"): + doc=FreeCAD.ActiveDocument + self._root_dict=doc.Robot_Description.Proxy.element_dict + self.edits=ModelEditor(self._root_dict) + else: + FreeCAD.Console.PrintMessage("document does not contain an assembly\n") + return + + def IsActive(self): + if hasattr(FreeCAD.ActiveDocument, "Robot_Description"): + return True + else: + return False + +FreeCADGui.addCommand("Model_Editor", Model_properties()) diff --git a/robot_descriptor/sdf_elements/atmosphere.py b/robot_descriptor/sdf_elements/atmosphere.py index a18af29..87ad8bf 100644 --- a/robot_descriptor/sdf_elements/atmosphere.py +++ b/robot_descriptor/sdf_elements/atmosphere.py @@ -1,6 +1,6 @@ -from .. import RD_globals +from .. import common #reponsible for creating an element tree using xml.etree -from ..RD_parser import initialize_element_tree +from ..RD_utils import initialize_element_tree import xml.etree.ElementTree as ET import FreeCAD @@ -87,23 +87,23 @@ def configUI(self): self.ui.atm_temp_grad.valueChanged.connect(self.on_temp_gradient) #callbacks def on_atm_temp(self): - RD_globals.set_xml_data(self._atm_elem,"temperature",False,self.properties.temperature) + common.set_xml_data(self._atm_elem,"temperature",False,self.properties.temperature) def on_type_change(self): - RD_globals.set_xml_data(self._atm_elem,"atmosphere",True,{"type":self.properties.type}) + common.set_xml_data(self._atm_elem,"atmosphere",True,{"type":self.properties.type}) def on_atm_pressure(self): - RD_globals.set_xml_data(self._atm_elem,"pressure",False,self.properties.pressure) + common.set_xml_data(self._atm_elem,"pressure",False,self.properties.pressure) def on_temp_gradient(self): - RD_globals.set_xml_data(self._atm_elem,"temperature_gradient",False,self.properties.temp_gradient) + common.set_xml_data(self._atm_elem,"temperature_gradient",False,self.properties.temp_gradient) #end callbacks def update_ui(self): - self.properties.temperature=float(RD_globals.get_xml_data(self._atm_elem,"temperature",False)) - self.properties.pressure=float(RD_globals.get_xml_data(self._atm_elem,"pressure",False)) - self.properties.temp_gradient=float(RD_globals.get_xml_data(self._atm_elem,"temperature_gradient",False)) + self.properties.temperature=float(common.get_xml_data(self._atm_elem,"temperature",False)) + self.properties.pressure=float(common.get_xml_data(self._atm_elem,"pressure",False)) + self.properties.temp_gradient=float(common.get_xml_data(self._atm_elem,"temperature_gradient",False)) #the reset method should also be used for extracting previously configured values @@ -117,7 +117,7 @@ def reset(self,default:bool=True): #use RD_globals parse dict to get the element doc=FreeCAD.ActiveDocument _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag]) + el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag]) if el_dict is not None: el_str=el_dict['elem_str'] self.merge(el_str) @@ -128,7 +128,7 @@ def reset(self,default:bool=True): self.update_ui() def merge(self, el_str): - RD_globals.merge_elements(self._atm_elem,ET.fromstring(el_str)) + common.merge_elements(self._atm_elem,ET.fromstring(el_str)) def is_checked(self): status=self.ui.atmosphere_group.isChecked() diff --git a/robot_descriptor/sdf_elements/collision.py b/robot_descriptor/sdf_elements/collision.py new file mode 100644 index 0000000..7533bab --- /dev/null +++ b/robot_descriptor/sdf_elements/collision.py @@ -0,0 +1,98 @@ +from ..RD_utils import initialize_element_tree +from .. import common +from . import surface +import copy +import os +import xml.etree.ElementTree as ET +import FreeCADGui ,FreeCAD + + +class collision_properties: + def __init__(self,ui): + self.ui=ui +#laser retro + @property + def laser_retro(self): + return self.ui.collision_laser_retro_sp.value() + @laser_retro.setter + def laser_retro(self,value): + self.ui.collision_laser_retro_sp.setValue(value) + +#max contacts + @property + def max_contacts(self): + return self.ui.collision_max_contacts_sp.value() + @max_contacts.setter + def max_contacts(self,value): + self.ui.collision_max_contacts_sp.setValue(value) + +#checkboxes + @property + def collision_laser_retro_cb(self): + return self.ui.collision_laser_retro_cb.isChecked() + + @property + def collison_max_contacts_cb(self): + return self.ui.collison_max_contacts_cb.isChecked() + + + +class collison: + def __init__(self,parent_ui=None): + #model editor ui + self.ui=parent_ui + self.tag='collision' + self.parennt_path='' + self.properties=collision_properties(self.ui) + self.file_name='collision.sdf' + self.collision_elem=initialize_element_tree.convdict_2_tree(self.file_name).get_element + #surface element + self.surface_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,"surface.ui")) + self.surface_cls=surface.surface(self.surface_ui) + self.ui.collision_scroll.setWidget(self.surface_ui) + self.configUI() + self.updateUI() + + def update_elements(self,item): + self.collision_elem=item.collision_element + self.surface_cls.update_element(item) + self.updateUI() + + def configUI(self): + self.ui.collision_max_contacts_sp.valueChanged.connect(self.on_max_contacts) + self.ui.collision_laser_retro_sp.valueChanged.connect( + lambda value: common.set_xml_data(self.collision_elem,"laser_retro",False,self.properties.laser_retro) + ) +#callabcks + + def on_max_contacts(self): + common.set_xml_data(self.collision_elem,"max_contacts",False,self.properties.max_contacts) + + +#end callbacks + + def updateUI(self): + data=["max_contacts","laser_retro"] + for item in data: + setattr(self.properties,item,common.get_xml_data(self.collision_elem,item,False)) + + + + def reset(self): + pass + + @property + def element(self): + t_collision_elem=copy.deepcopy(self.collision_elem) + if not self.properties.collision_laser_retro_cb: + t_collision_elem.remove("laser_retro") + + if not self.properties.collison_max_contacts_cb: + t_collision_elem.remove("max_contacts") + + t_surface=self.surface_cls.element + + if t_collision_elem.find('surface') is None: + t_collision_elem.append(t_surface) + return t_collision_elem + \ No newline at end of file diff --git a/robot_descriptor/sdf_elements/light.py b/robot_descriptor/sdf_elements/light.py index 44d34ba..5f9c10b 100644 --- a/robot_descriptor/sdf_elements/light.py +++ b/robot_descriptor/sdf_elements/light.py @@ -1,9 +1,10 @@ +from typing import Any import xml.etree.ElementTree as ET from PySide import QtCore from PySide.QtGui import QMessageBox import FreeCAD -from ..RD_parser import initialize_element_tree -from .. import RD_globals +from ..RD_utils import initialize_element_tree +from .. import common import copy import re from PySide.QtGui import QColorDialog @@ -194,7 +195,7 @@ def pose(self,vals:list): #light #================================================================= -class light(RD_globals.color_pickr): +class light(common.color_pickr): def __init__(self,ui) -> None: self.ui=ui self.file_name='light.sdf' @@ -221,6 +222,7 @@ def initialize(self): del self.pose.attrib["degrees"] # append pose to light self._light_element.append(self.pose) + #this variable will store all the lights added to th world self.lights={} #the lights dictionary format # @@ -247,7 +249,7 @@ def add_sun(self): 'quadratic':0.001} for key in sun_properties.keys(): - RD_globals.set_xml_data(sun,key,False,sun_properties[key]) + common.set_xml_data(sun,key,False,sun_properties[key]) #append to sun self.lights['sun']=copy.deepcopy(sun) @@ -272,7 +274,7 @@ def configUI(self): #type self.ui.light_type.currentTextChanged.connect(self.on_type) #intensity - self.ui.intensity_sp.valueChanged.connect(self.on_intensity) + self.ui.intensity_sp.valueChanged.connect(lambda : common.set_xml_data(self._current_light_element,"intensity",False,self.properties.intensity)) #shadows self.ui.cast_shadows_check_b.stateChanged.connect(self.on_cast_shadows) #visualize @@ -377,7 +379,7 @@ def on_name(self): #update the current name self.current_light=name #update the values in the ui - self.properties.name=RD_globals.get_xml_data(self._current_light_element,[self.tag,'name'],True) + self.properties.name=common.get_xml_data(self._current_light_element,[self.tag,'name'],True) #update type name in the list widget #get current iten current_item=self.ui.light_listWidget.currentRow() @@ -402,52 +404,49 @@ def on_type(self): else: self.ui.direction_groupbox.setEnabled(False) - def on_intensity(self): - RD_globals.set_xml_data(self._current_light_element,"intensity",False,self.properties.intensity) - def on_cast_shadows(self): - RD_globals.set_xml_data(self._current_light_element,"cast_shadows",False,self.properties.cast_shadows) + common.set_xml_data(self._current_light_element,"cast_shadows",False,self.properties.cast_shadows) def on_visualize(self): - RD_globals.set_xml_data(self._current_light_element,"visualize",False,self.properties.visualize) + common.set_xml_data(self._current_light_element,"visualize",False,self.properties.visualize) def on_light(self): - RD_globals.set_xml_data(self._current_light_element,"light_on",False,self.properties.light_on) + common.set_xml_data(self._current_light_element,"light_on",False,self.properties.light_on) def on_diffuse(self): - RD_globals.set_xml_data(self._current_light_element,"diffuse",False,self.properties.diffuse) + common.set_xml_data(self._current_light_element,"diffuse",False,self.properties.diffuse) self.set_widget_color('diffuse',self.ui.light_diffuse_color_pkr) def on_specular(self): - RD_globals.set_xml_data(self._current_light_element,"specular",False,self.properties.specular) + common.set_xml_data(self._current_light_element,"specular",False,self.properties.specular) self.set_widget_color('specular',self.ui.light_specular_color_pkr) def on_range(self): - RD_globals.set_xml_data(self._current_light_element,"range",False,self.properties.range) + common.set_xml_data(self._current_light_element,"range",False,self.properties.range) def on_constant(self): - RD_globals.set_xml_data(self._current_light_element,"constant",False,self.properties.constant) + common.set_xml_data(self._current_light_element,"constant",False,self.properties.constant) def on_linear(self): - RD_globals.set_xml_data(self._current_light_element,"linear",False,self.properties.linear) + common.set_xml_data(self._current_light_element,"linear",False,self.properties.linear) def on_quadratic(self): - RD_globals.set_xml_data(self._current_light_element,"quadratic",False,self.properties.quadratic) + common.set_xml_data(self._current_light_element,"quadratic",False,self.properties.quadratic) def on_pose(self): - RD_globals.set_xml_data(self._current_light_element,"pose",False,self.properties.pose) + common.set_xml_data(self._current_light_element,"pose",False,self.properties.pose) def on_direction(self): - RD_globals.set_xml_data(self._current_light_element,"direction",False,self.properties.direction) + common.set_xml_data(self._current_light_element,"direction",False,self.properties.direction) def on_inner_angle(self): - RD_globals.set_xml_data(self._current_light_element,"inner_angle",False,self.properties.inner_angle) + common.set_xml_data(self._current_light_element,"inner_angle",False,self.properties.inner_angle) def on_outer_angle(self): - RD_globals.set_xml_data(self._current_light_element,"outer_angle",False,self.properties.outer_angle) + common.set_xml_data(self._current_light_element,"outer_angle",False,self.properties.outer_angle) def on_falloff(self): - RD_globals.set_xml_data(self._current_light_element,"falloff",False,self.properties.falloff) + common.set_xml_data(self._current_light_element,"falloff",False,self.properties.falloff) def on_add(self): @@ -512,25 +511,25 @@ def on_remove(self): #update ui def update_ui(self): - self.properties.name=RD_globals.get_xml_data(self._current_light_element,[self.tag,'name'],True) - self.properties.type=RD_globals.get_xml_data(self._current_light_element,['light','type'],True) - self.properties.intensity=float(RD_globals.get_xml_data(self._current_light_element,"intensity",False)) - self.properties.cast_shadows=RD_globals.get_xml_data(self._current_light_element,"cast_shadows",False) - self.properties.visualize=RD_globals.get_xml_data(self._current_light_element,"visualize",False) - self.properties.light_on=RD_globals.get_xml_data(self._current_light_element,"light_on",False) - self.properties.diffuse=RD_globals.get_xml_data(self._current_light_element,"diffuse",False) + self.properties.name=common.get_xml_data(self._current_light_element,[self.tag,'name'],True) + self.properties.type=common.get_xml_data(self._current_light_element,['light','type'],True) + self.properties.intensity=float(common.get_xml_data(self._current_light_element,"intensity",False)) + self.properties.cast_shadows=common.get_xml_data(self._current_light_element,"cast_shadows",False) + self.properties.visualize=common.get_xml_data(self._current_light_element,"visualize",False) + self.properties.light_on=common.get_xml_data(self._current_light_element,"light_on",False) + self.properties.diffuse=common.get_xml_data(self._current_light_element,"diffuse",False) - self.properties.specular=RD_globals.get_xml_data(self._current_light_element,"specular",False) - self.properties.range=float(RD_globals.get_xml_data(self._current_light_element,"range",False)) - self.properties.constant=float(RD_globals.get_xml_data(self._current_light_element,"constant",False)) - self.properties.linear=float(RD_globals.get_xml_data(self._current_light_element,"linear",False)) - self.properties.quadratic=float(RD_globals.get_xml_data(self._current_light_element,"quadratic",False)) + self.properties.specular=common.get_xml_data(self._current_light_element,"specular",False) + self.properties.range=float(common.get_xml_data(self._current_light_element,"range",False)) + self.properties.constant=float(common.get_xml_data(self._current_light_element,"constant",False)) + self.properties.linear=float(common.get_xml_data(self._current_light_element,"linear",False)) + self.properties.quadratic=float(common.get_xml_data(self._current_light_element,"quadratic",False)) - self.properties.pose=RD_globals.get_xml_data(self._current_light_element,"pose",False) - self.properties.direction=RD_globals.get_xml_data(self._current_light_element,"direction",False) - self.properties.inner_angle=float(RD_globals.get_xml_data(self._current_light_element,"inner_angle",False)) - self.properties.outer_angle=float(RD_globals.get_xml_data(self._current_light_element,"outer_angle",False)) - self.properties.falloff=float(RD_globals.get_xml_data(self._current_light_element,"falloff",False)) + self.properties.pose=common.get_xml_data(self._current_light_element,"pose",False) + self.properties.direction=common.get_xml_data(self._current_light_element,"direction",False) + self.properties.inner_angle=float(common.get_xml_data(self._current_light_element,"inner_angle",False)) + self.properties.outer_angle=float(common.get_xml_data(self._current_light_element,"outer_angle",False)) + self.properties.falloff=float(common.get_xml_data(self._current_light_element,"falloff",False)) #set color picker button colors self.set_widget_color('diffuse',self.ui.light_diffuse_color_pkr) @@ -549,7 +548,7 @@ def reset(self,default:bool=True): direction=self._light_element.find('direction') doc=FreeCAD.ActiveDocument _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag]) + el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag]) if el_dict is not None: #clear list widget an light self.ui.light_listWidget.clear() @@ -583,6 +582,7 @@ def reset(self,default:bool=True): @property def element(self): + #get all the lights el_dict=copy.deepcopy(self.lights) el_list=[] #remove elements depending on type selection diff --git a/robot_descriptor/sdf_elements/link.py b/robot_descriptor/sdf_elements/link.py new file mode 100644 index 0000000..47bf6e8 --- /dev/null +++ b/robot_descriptor/sdf_elements/link.py @@ -0,0 +1,378 @@ +import FreeCAD +from .. import common +from ..RD_utils import initialize_element_tree +import copy +from PySide import QtCore +import xml.etree.ElementTree as ET +import FreeCADGui +import os +from PySide2.QtWidgets import QTreeView +from PySide2.QtGui import QStandardItemModel + +class link_properties: + def __init__(self,ui) -> None: + self.ui=ui + +#gravity + @property + def gravity(self): + + state= self.ui.link_gravity_checkbox.isChecked() + if state: + return str('true') + else: + return str('false') + + @gravity.setter + def gravity(self,state): + if state=='true': + self.ui.link_gravity_checkbox.setCheckState(QtCore.Qt.Checked) + else: + self.ui.link_gravity_checkbox.setCheckState(QtCore.Qt.Unchecked) + +#enable wind + @property + def enable_wind(self): + state=self.ui.link_enable_wind_checkbox.isChecked() + if state: + return str('true') + else: + return str('false') + + @enable_wind.setter + def enable_wind(self,state): + self.ui.link_enable_wind_checkbox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.link_enable_wind_checkbox.setCheckState(QtCore.Qt.Unchecked) + + + +#self_collide + @property + def self_collide(self): + return str('true') if self.ui.link_self_collide_checkbox.isChecked() else str('false') + + @self_collide.setter + def self_collide(self,state): + self.ui.link_self_collide_checkbox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.link_self_collide_checkbox.setCheckState(QtCore.Qt.Unchecked) + +#kinematic + @property + def kinematic(self): + return str('true') if self.ui.link_kinematic_checkbox.isChecked() else str('false') + @kinematic.setter + def kinematic(self,state): + self.ui.link_kinematic_checkbox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.link_kinematic_checkbox.setCheckState(QtCore.Qt.Unchecked) + +#velocity decay + #linear + @property + def linear(self): + return self.ui.velocity_decay_linear_sp.value() + @linear.setter + def linear(self,value): + self.ui.velocity_decay_linear_sp.setValue(value) + + #angular + @property + def angular(self): + return self.ui.link_angular_vel_decay_sp.value() + @angular.setter + def angular(self,value): + self.ui.link_angular_vel_decay_sp.setValue(value) + +#inertial +#fam -> fluid added mass +#xx + @property + def fam_xx(self): + return self.ui.fam_xx_sp.value() + @fam_xx.setter + def fam_xx(self,value): + self.ui.fam_xx_sp.setValue(value) +#xy + @property + def fam_xy(self): + return self.ui.fam_xy_sp.value() + @fam_xy.setter + def fam_xy(self,value): + self.ui.fam_xy_sp.setValue(value) +#xz + @property + def fam_xz(self): + return self.ui.fam_xz_sp.value() + @fam_xz.setter + def fam_xz(self,value): + self.ui.fam_xz_sp.setValue(value) + +#p + @property + def fam_xp(self): + return self.ui.fam_xp_sp.value() + @fam_xp.setter + def fam_xp(self,value): + self.ui.fam_xp_sp.setValue(value) + +#xq + @property + def fam_xq(self): + return self.ui.fam_xq_sp.value() + + @fam_xq.setter + def fam_xq(self,value): + self.ui.fam_xq_sp.setValue(value) + +#xr + @property + def fam_xr(self): + return self.ui.value() + @fam_xr.setter + def fam_xr(self,value): + self.ui.fam_xr_sp.setValue(value) + +#yy + @property + def fam_yy(self): + return self.ui.fam_yy_sp.value() + @fam_yy.setter + def fam_yy(self,val): + self.ui.fam_yy_sp.setValue(val) + +#yz + @property + def fam_yz(self): + return self.ui.fam_yz_sp.value() + @fam_yz.setter + def fam_yz(self,val): + self.ui.fam_yz_sp.setValue(val) + +#yp + @property + def fam_yp(self): + return self.ui.fam_yp_sp.value() + @fam_yp.setter + def fam_yp(self,value): + self.ui.fam_yp_sp.setValue(value) + +#yq + @property + def fam_yq(self): + return self.ui.fam_yq_sp.value() + @fam_yq.setter + def fam_yq(self,val): + self.ui.fam_yq.setValue(val) +#yr + @property + def fam_yr(self): + return self.ui.fam_yr_sp.value() + @fam_yr.setter + def fam_yr(self,val): + self.ui.fam_yr_sp.setValue(val) + +#zz + @property + def fam_zz(self): + return self.ui.fam_zz_sp.value() + @fam_zz.setter + def fam_zz(self,value): + self.ui.fam_zz_sp.setValue(value) +#zp + @property + def fam_zp(self): + return self.ui.fam_zp_sp.value() + @fam_zp.setter + def fam_zp(self,val): + self.ui.fam_zp_sp.setValue(val) + +#zq + @property + def fam_zq(self): + return self.ui.fam_zq_sp.value() + @fam_zq.setter + def fam_zp(self,val): + self.ui.fam_zq_sp.setValue(val) + +#zr + @property + def fam_zr(self): + return self.ui.fam_zr_sp.value() + @fam_zr.setter + def fam_zr(self,val): + return self.ui.fam_zr_sp.setValue(val) + +#pp + @property + def fam_pp(self): + return self.ui.fam_pp_sp.value() + @fam_pp.setter + def fam_pp(self,value): + self.ui.fam_pp_sp.setValue(value) + +#pq + @property + def fam_pq(self): + return self.ui.fam_pq_sp.value() + @fam_pq.setter + def fam_pq(self,val): + self.ui.fam_pq_sp.setValue(val) + +#pr + @property + def fam_pr(self): + return self.ui.fam_pr_sp.value() + @fam_pr.setter + def fam_pr(self,val): + self.ui.fam_pr_sp.setValue(val) +#qq + @property + def fam_qq(self): + return self.ui.fam_qq_sp.value() + @fam_qq.setter + def fam_qq(self,val): + self.ui.fam_qq_sp.setValue(val) + +#qr + @property + def fam_qr(self): + return self.ui.fam_qr_sp.value() + @fam_qr.setter + def fam_qr(self,val): + self.ui.fam_qr_sp.setValue(val) + +#rr + @property + def fam_rr(self): + return self.ui.fam_rr_sp.value() + @fam_rr.setter + def fam_rr(self,val): + self.ui.fam_rr_sp.setValue(val) + +#====================== +#link +#==================== +class link: + def __init__(self,parent_ui,elem_struct=None): + self.ui=parent_ui + self.file_name='link.sdf' + self.tag='link' + + #models will be store as children of sdf + self.parent_path=['sdf','model'] + self.properties=link_properties(self.ui) + self._inertial_element=initialize_element_tree.convdict_2_tree("inertial.sdf").get_element + + self.link_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element + # self.link_element.append(self._inertial_element) + self._root_dict=elem_struct + self.configUI() + self.UpdateUi() +# this will be called for the item + + def update_elements(self,item): + self.link_element=item._link_element + self._inertial_element=item._inertial_element + #update the ui after reset + self.UpdateUi() + + def configUI(self): + self.ui.link_gravity_checkbox.stateChanged.connect(self.onGravity) + self.ui.link_enable_wind_checkbox.stateChanged.connect(self.onEnableWind) + self.ui.link_self_collide_checkbox.stateChanged.connect(self.onSelfCollide) + self.ui.link_kinematic_checkbox.stateChanged.connect(self.onKinematic) + self.ui.velocity_decay_linear_sp.valueChanged.connect(self.onLinear) + self.ui.link_angular_vel_decay_sp.valueChanged.connect(self.onAngular) + #inertial + # fam=self._inertial_element.find(".//fluid_added_mass") + # fam every time the lmbda is called fam gets updated + #the lambda expression captures self ,therefore updates made to all local variables of self will reflected for + # each lambda call + self.ui.fam_xx_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xx',False,self.properties.fam_xx) ) + self.ui.fam_xy_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xy',False,self.properties.fam_xy) ) + self.ui.fam_xz_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xz',False,self.properties.fam_xz) ) + + self.ui.fam_xp_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xp',False,self.properties.fam_xp) ) + self.ui.fam_xq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xq',False,self.properties.fam_xq) ) + self.ui.fam_xr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xr',False,self.properties.fam_xr) ) + + #y + self.ui.fam_yy_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yy',False,self.properties.fam_yy)) + self.ui.fam_yz_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yz',False,self.properties.fam_yz)) + + self.ui.fam_yp_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yp',False,self.properties.fam_yp)) + self.ui.fam_yq_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yq',False,self.properties.fam_yq)) + self.ui.fam_yr_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yr',False,self.properties.fam_yr)) + + #z + self.ui.fam_zz_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zz',False,self.properties.fam_zz)) + self.ui.fam_zp_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zp',False,self.properties.fam_zp)) + self.ui.fam_zq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zq',False,self.properties.fam_zq)) + self.ui.fam_zr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zr',False,self.properties.fam_zr)) + + #p + self.ui.fam_pp_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'pp',False,self.properties.fam_pp)) + self.ui.fam_pq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'pq',False,self.properties.fam_pq)) + self.ui.fam_pr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'pr',False,self.properties.fam_pr)) + + self.ui.fam_qq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'qq',False,self.properties.fam_qq)) + self.ui.fam_qr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'qr',False,self.properties.fam_qr)) + self.ui.fam_rr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'rr',False,self.properties.fam_rr)) + + + + +#end configUI + def onGravity(self): + common.set_xml_data(self.link_element,'gravity',False,self.properties.gravity) + + def onEnableWind(self): + common.set_xml_data(self.link_element,'enable_wind',False,self.properties.enable_wind) + + def onSelfCollide(self): + common.set_xml_data(self.link_element,'self_collide',False,self.properties.self_collide) + + def onKinematic(self): + common.set_xml_data(self.link_element,'kinematic',False,self.properties.kinematic) + + def onLinear(self): + common.set_xml_data(self.link_element,'linear',False,self.properties.linear) + + def onAngular(self): + common.set_xml_data(self.link_element,'angular',False,self.properties.angular) + + #element to be updaed sent to the list + def UpdateUi(self): + element=self.link_element + self.properties.gravity=common.get_xml_data(element,'gravity',False) + self.properties.enable_wind=common.get_xml_data(element,'enable_wind',False) + self.properties.self_collide=common.get_xml_data(element,'self_collide',False) + self.properties.kinematic= common.get_xml_data(element,'kinematic',False) + self.properties.linear=common.get_xml_data(element,'linear',False) + self.properties.angular=common.get_xml_data(element,'angular',False) + fam=self._inertial_element.find(".//fluid_added_mass") + elem_ui_pairs={"xx":"fam_xx_sp","xy":"fam_xy_sp","xz":"fam_xz_sp","xp":"fam_xp_sp","xq":"fam_xq_sp","xr":"fam_xr_sp", + "yy":"fam_yy_sp","yz":"fam_yz_sp","yp":"fam_yp_sp","yq":"fam_yq_sp","yr":"fam_yr_sp","zz":"fam_zz_sp", + "zp":"fam_zp_sp","zq":"fam_zq_sp","zr":"fam_zr_sp","pp":"fam_pp_sp","pr":"fam_pr_sp","pq":"fam_pq_sp", + "qq":"fam_qq_sp","qr":"fam_qr_sp","rr":"fam_rr_sp"} + for tag in elem_ui_pairs.keys(): + setattr(self.properties,elem_ui_pairs[tag],common.get_xml_data(fam,tag,False)) + + #this needs to reset the data of all links in the model + #how will this information be extracted + def reset(self,default=True): + pass + @property + def element(self): + t_link_elem=copy.deepcopy(self.link_element) + + if not self.ui.link_state_groupbox.isChecked(): + for tag in ["gravity","enable_wind","self_collide","kinematic"]: + t_link_elem.remove(t_link_elem.find(tag)) + + if self.ui.link_velocity_decay_groupbox.isChecked(): + t_link_elem.remove(t_link_elem.find("velocity_decay")) + + t_inertial_elem=copy.deepcopy(self._inertial_element) + if self.ui.fluid_added_mass_groupbox.isChecked(): + t_inertial_elem.remove(t_inertial_elem.find("fluid_added_mass")) + + if t_link_elem.find("inertial") is None: + t_link_elem.append(t_inertial_elem) + return t_link_elem \ No newline at end of file diff --git a/robot_descriptor/sdf_elements/material.py b/robot_descriptor/sdf_elements/material.py new file mode 100644 index 0000000..e4d05d8 --- /dev/null +++ b/robot_descriptor/sdf_elements/material.py @@ -0,0 +1,798 @@ +from .. import common +from ..RD_utils import initialize_element_tree +import copy +from PySide import QtGui,QtCore +import re +import math +import csv +# import Spreadsheet +import os +import xml.etree.ElementTree as ET +import FreeCAD ,FreeCADGui + +#matreial +class material_properties: + def __init__(self,ui) -> None: + self.ui=ui +#script uri + @property + def script_uri(self): + return self.ui.material_script_uri_input.text() + @script_uri.setter + def script_uri(self,text): + self.ui.material_script_uri_input.setText(text) + +#script name + @property + def script_name(self): + return self.ui.material_script_name.text() + @script_name.setter + def script_name(self,text): + self.ui.material_script_name.setText(text) + +#shader_type + @property + def shader_type(self): + return self.ui.shader_type.currentText() + @shader_type.setter + def shader_type(self,text): + self.ui.shader_type.setCurrentText(text) +#normal map + @property + def normal_map(self): + return self.ui.material_normal_map_input.text() + @normal_map.setter + def normal_map(self,text): + self.ui.material_normal_map_input.setText(text) + + + +#render order + @property + def render_order(self): + return self.ui.material_render_order_sp.value() + @render_order.setter + def render_order(self,value): + self.ui.material_render_order_sp.setValue(value) + +#shininess + @property + def shininess(self): + return self.ui.material_shininess_sp.value() + @shininess.setter + def shininess(self,value): + self.ui.material_shininess_sp.setValue(value) + +#lighting + @property + def lighting(self): + state= self.ui.material_lighting_checkbox.isChecked() + if state is True: + return str('true') + else: + return str('false') + @lighting.setter + def lighting(self,state): + if state =='true': + self.ui.material_lighting_checkbox.setCheckState(QtCore.Qt.Checked) + else: + self.ui.material_lighting_checkbox.setCheckState(QtCore.Qt.Unchecked) + + +#ambient + @property + def ambient(self): + return [self.ui.material_ambient_R_sp.value(),self.ui.material_ambient_G_sp.value(), + self.ui.material_ambient_B_sp.value(),self.ui.material_ambient_A_sp.value()] + @ambient.setter + def ambient(self,vals): + self.ui.material_ambient_R_sp.setValue(vals[0]) + self.ui.material_ambient_G_sp.setValue(vals[1]) + self.ui.material_ambient_B_sp.setValue(vals[2]) + self.ui.material_ambient_A_sp.setValue(vals[3]) +#diffuse + @property + def diffuse(self): + return [self.ui.material_diffuse_R_sp.value(),self.ui.material_diffuse_G_sp.value(), + self.ui.material_diffuse_B_sp.value(),self.ui.material_diffuse_A_sp.value()] + @diffuse.setter + def diffuse(self,vals): + self.ui.material_diffuse_R_sp.setValue(vals[0]) + self.ui.material_diffuse_G_sp.setValue(vals[1]) + self.ui.material_diffuse_B_sp.setValue(vals[2]) + self.ui.material_diffuse_A_sp.setValue(vals[3]) +#specular + @property + def specular(self): + return [self.ui.material_specular_R_sp.value(),self.ui.material_specular_G_sp.value(), + self.ui.material_specular_B_sp.value(),self.ui.material_specular_A_sp.value()] + @specular.setter + def specular(self,vals): + self.ui.material_specular_R_sp.setValue(vals[0]) + self.ui.material_specular_G_sp.setValue(vals[1]) + self.ui.material_specular_B_sp.setValue(vals[2]) + self.ui.material_specular_A_sp.setValue(vals[3]) +#emissive + @property + def emissive(self): + return [self.ui.material_emissive_R_sp.value(),self.ui.material_emissive_G_sp.value(), + self.ui.material_emissive_B_sp.value(),self.ui.material_emissive_A_sp.value()] + @emissive.setter + def emissive(self,vals): + self.ui.material_emissive_R_sp.setValue(vals[0]) + self.ui.material_emissive_G_sp.setValue(vals[1]) + self.ui.material_emissive_B_sp.setValue(vals[2]) + self.ui.material_emissive_A_sp.setValue(vals[3]) + +#pbr +#================================================= + @property + def double_sided(self): + return str('true') if self.ui.material_double_sided_checkBox.isChecked() else str('false') + + @double_sided.setter + def double_sided(self,state): + self.ui.material_double_sided_checkBox.setCheckState(QtCore.Qt.Checked) if state else self.ui.material_double_sided_checkBox.setCheckState(QtCore.Qt.Unchecked) + +#metal_albedo_map + @property + def metal_albedo_map(self): + return self.ui.metal_albedo_map_lineEdit.text() + @metal_albedo_map.setter + def metal_albedo_map(self,text): + self.ui.metal_albedo_map_lineEdit.setText(text) + +#metal_roughness_map + @property + def metal_roughness_map(self): + return self.ui.metal_roughness_map_lineEdit.text() + @metal_roughness_map.setter + def metal_roughness_map(self,text): + self.ui.metal_roughness_map_lineEdit.setText(text) + +#metal_roughness + @property + def metal_roughness(self): + return self.ui.metal_roughness_lineEdit.text() + @metal_roughness.setter + def metal_roughness(self,text): + self.ui.metal_roughness_lineEdit.setText(text) + +#metalness_map + @property + def metalness_map(self): + return self.ui.metalness_map_lineEdit.text() + @metalness_map.setter + def metalness_map(self,text): + self.ui.metalness_map_lineEdit.setText(text) + +#metalness + @property + def metalness(self): + return self.ui.metalness_sp.value() + @metalness.setter + def metalness(self,val): + + self.ui.metalness_sp.setValue(val) + +#metal_environment_map + @property + def metal_environment_map(self): + return self.ui.metal_environment_map_lineEdit.text() + @metal_environment_map.setter + def metal_environment_map(self,text): + self.ui.metal_environment_map_lineEdit.setText(text) + +#metal_ambient_occlusion_map + @property + def metal_ambient_occlusion_map(self): + return self.ui.metal_ambient_occlusion_map_lineEdit.text() + @metal_ambient_occlusion_map.setter + def metal_ambient_occlusion_map(self,text): + self.ui.metal_ambient_occlusion_map_lineEdit.setText(text) + +#metal_emissive_map + @property + def metal_emissive_map(self): + return self.ui.metal_emissive_map_lineEdit.text() + @metal_emissive_map.setter + def metal_emissive_map(self,text): + self.ui.metal_emissive_map_lineEdit.setText(text) + +#metal_light_map + @property + def metal_light_map(self): + return self.ui.metal_light_map_lineEdit.text() + @metal_light_map.setter + def metal_light_map(self,text): + self.ui.metal_light_map_lineEdit.setText(text) + +#metal_uv_set + @property + def metal_uv_set(self): + return self.ui.metal_uv_set_sp.value() + @metal_uv_set.setter + def metal_uv_set(self,value): + self.ui.metal_uv_set_sp.setValue(value) + +#metal_normal_map + @property + def metal_normal_map(self): + return self.ui.metal_normal_map_lineEdit.text() + @metal_normal_map.setter + def metal_normal_map(self,text): + self.ui.metal_normal_map_lineEdit.setText(text) + +#metal_normal_map_type + @property + def metal_normal_map_type(self): + return self.ui.metal_normal_map_type_comboBox.currentText() + + @metal_normal_map_type.setter + def metal_normal_map_type(self,text): + self.ui.metal_normal_map_type_comboBox.setCurrentText(text) + +#========== +#specular + +#specular_albedo_map + @property + def specular_albedo_map(self): + return self.ui.specular_albedo_map_lineEdit.text() + @specular_albedo_map.setter + def specular_albedo_map(self,text): + self.ui.specular_albedo_map_lineEdit.setText(text) + +#specular_map + @property + def specular_map(self): + self.ui.specular_map_lineEdit.text() + @specular_map.setter + def specular_map(self,text): + self.ui.specular_map_lineEdit.setText(text) + +#specular_glossiness + @property + def specular_glossiness(self): + return self.ui.specular_glossiness_sp.value() + @specular_glossiness.setter + def specular_glossiness(self,val): + self.ui.specular_glossiness_sp.setValue(val) + +#specular_environment_map + @property + def specular_environment_map(self): + return self.ui.specular_environment_map_lineEdit.text() + @specular_environment_map.setter + def specular_environment_map(self,text): + self.ui.specular_environment_map_lineEdit.setText(text) + +#specular_ambient_occlusion_map + @property + def specular_ambient_occlusion_map(self): + return self.ui.specular_ambient_occlusion_map_lineEdit.text() + @specular_ambient_occlusion_map.setter + def specular_ambient_occlusion_map(self,text): + self.ui.specular_ambient_occlusion_map_lineEdit.setText(text) + +#specular_emissive_map + @property + def specular_emissive_map(self): + return self.ui.specular_emissive_map_lineEdit.text() + @specular_emissive_map.setter + def specular_emissive_map(self,text): + self.ui.specular_emissive_map_lineEdit.setText(text) + +#specular_glossiness_map + @property + def specular_glossiness_map(self): + return self.ui.specular_glossiness_map_lineEdit.text() + @specular_glossiness_map.setter + def specular_glossiness_map(self,text): + self.ui.specular_glossiness_map_lineEdit.setText(text) + +#specular_light_map + @property + def specular_light_map(self): + return self.ui.specular_light_map_lineEdit.text() + @specular_light_map.setter + def specular_light_map(self,text): + self.ui.specular_light_map_lineEdit.setText(text) + +#specular_uv_set + @property + def specular_uv_set(self): + return self.ui.specular_uv_set_sp.value() + @specular_uv_set.setter + def specular_uv_set(self,val): + self.ui.specular_uv_set_sp.setValue(val) + +#specular_normal_map + @property + def specular_normal_map(self): + return self.ui.specular_normal_map_lineEdit.text() + @specular_normal_map.setter + def specular_normal_map(self,text): + self.ui.specular_normal_map_lineEdit.setText(text) + +#specular_normal_map_type + @property + def specular_normal_map_type(self): + return self.ui.specular_normal_map_type_comboBox.currentText() + @specular_normal_map_type.setter + def specular_normal_map_type(self,text): + self.ui.specular_normal_map_type_comboBox.setCurrentText(text) + +#Read only attributes +#used for optional properties +#pbr + #metal + @property + def metal_albedo_map_cb(self): + return self.ui.metal_albedo_map_checkBox.isChecked() + + @property + def metal_roughness_map_cb(self): + return self.ui.metal_roughness_map_checkBox.isChecked() + + @property + def metal_roughness_cb(self): + return self.ui.metal_roughness_checkBox.isChecked() + @property + def metalness_map_cb(self): + return self.ui.metalness_map_checkBox.isChecked() + + @property + def metalness_cb(self): + return self.ui.metalness_checkBox.isChecked() + @property + def metal_environment_map_cb(self): + return self.ui.metal_environment_map_checkBox.isChecked() + @property + def metal_ambient_occlusion_map_cb(self): + return self.ui.metal_ambient_occlusion_map_checkBox.isChecked() + + @property + def metal_emissive_map_cb(self): + return self.ui.metal_emissive_map_checkBox.isChecked() + @property + def metal_normal_map_cb(self): + return self.ui.metal_normal_map_groupBox.isChecked() + + @property + def metal_light_map_cb(self): + return self.ui.metal_light_map_groupBox.isChecked() + + #specular + @property + def specular_albedo_map_cb(self): + return self.ui.specular_albedo_map_checkBox.isChecked() + @property + def specular_map_cb(self): + return self.ui.specular_map_checkBox.isChecked() + @property + def specular_glossiness_cb(self): + return self.ui.specular_glossiness_checkBox.isChecked() + @property + def specular_environment_map_cb(self): + return self.ui.specular_environment_map_checkBox.isChecked() + @property + def specular_ambient_occlusion_map_cb(self): + return self.ui.specular_ambient_occlusion_map_checkBox.isChecked() + @property + def specular_emissive_map_cb(self): + return self.ui.specular_emissive_map_checkBox.isChecked() + @property + def specular_glossiness_map_cb(self): + return self.ui.specular_glossiness_map_checkBox.isChecked() + @property + def specular_light_map_cb(self): + return self.ui.specular_light_map_groupBox.isChecked() + @property + def specular_normal_map_cb(self): + return self.ui.specular_normal_map_groupBox.isChecked() + + #pbr cb + @property + def pbr_enabled(self): + return self.ui.material_pbr_groupbox.isChecked() + #metal cb + @property + def metal_enabled(self): + return self.ui.material_metal_groupbox.isChecked() + #speculat cb + @property + def specular_enabled(self): + return self.ui.pbr_specular_groupBox.isChecked() + + + +#=========================================== +#=========================================== +#material element +#============================================ +#============================================ +class material(common.color_pickr): + #since material has multiple parents let the parent class + # the parent and parent path data + def __init__(self,ui) -> None: + super().__init__() + self.ui=ui + #use the road tag since material will be implemented as part of the road element + self.tag='road' + self.parent_path='' + self.file_name='material.sdf' + + self._material_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element + self.properties=material_properties(self.ui) + self.configUI() + # self.reset(default=False) + + def update_elements(self,item): + self._material_element=item._material_element + self.updateUi() + + def configUI(self): + self.ui.material_script_uri_input.textEdited.connect(self.on_uri) + self.ui.material_script_name.textEdited.connect(self.on_uri_name) + self.ui.shader_type.currentTextChanged.connect(self.on_shader_type) + self.ui.material_normal_map_input.textEdited.connect(self.on_normal_map) + self.ui.material_render_order_sp.valueChanged.connect(self.on_material_render_ord) + self.ui.material_shininess_sp.valueChanged.connect(self.on_shininess) + + self.ui.material_lighting_checkbox.stateChanged.connect( + lambda : common.set_xml_data(self._material_element,"lighting",False,self.properties.lighting) + ) + + #ambient + self.ui.material_ambient_R_sp.valueChanged.connect(self.on_ambient) + self.ui.material_ambient_G_sp.valueChanged.connect(self.on_ambient) + self.ui.material_ambient_B_sp.valueChanged.connect(self.on_ambient) + self.ui.material_ambient_A_sp.valueChanged.connect(self.on_ambient) + #diffuse + self.ui.material_diffuse_R_sp.valueChanged.connect(self.on_diffuse) + self.ui.material_diffuse_G_sp.valueChanged.connect(self.on_diffuse) + self.ui.material_diffuse_B_sp.valueChanged.connect(self.on_diffuse) + self.ui.material_diffuse_A_sp.valueChanged.connect(self.on_diffuse) + #specular + self.ui.material_specular_R_sp.valueChanged.connect(self.on_specular) + self.ui.material_specular_G_sp.valueChanged.connect(self.on_specular) + self.ui.material_specular_B_sp.valueChanged.connect(self.on_specular) + self.ui.material_specular_A_sp.valueChanged.connect(self.on_specular) + #emissive + self.ui.material_emissive_R_sp.valueChanged.connect(self.on_emissive) + self.ui.material_emissive_G_sp.valueChanged.connect(self.on_emissive) + self.ui.material_emissive_B_sp.valueChanged.connect(self.on_emissive) + self.ui.material_emissive_A_sp.valueChanged.connect(self.on_emissive) + + #color picker buttons + self.ui.material_ambient_color_pkr.clicked.connect(self.on_ambient_color_pkr) + self.ui.material_diffuse_color_pkr.clicked.connect(self.on_diffuse_color_pkr) + self.ui.material_specular_color_pkr.clicked.connect(self.on_specular_color_pkr) + self.ui.material_emissive_color_pkr.clicked.connect(self.on_emissive_color_pkr) + + +#pbr + #metal + #properties under the metal element + self.ui.metal_albedo_map_lineEdit.textEdited.connect(self.on_metal_albedo_map) + + self.ui.metal_roughness_map_lineEdit.textEdited.connect(self.on_metal_roughness_map) + self.ui.metal_roughness_lineEdit.textEdited.connect(self.on_metal_roughness) + + self.ui.metalness_map_lineEdit.textEdited.connect(self.on_metalness_map) + + self.ui.metalness_sp.valueChanged.connect(self.on_metalness) + + self.ui.metal_environment_map_lineEdit.textEdited.connect(self.on_metal_environment_map) + + self.ui.metal_ambient_occlusion_map_lineEdit.textEdited.connect(self.on_metal_ambient_occlusion_map) + + self.ui.metal_emissive_map_lineEdit.textEdited.connect(self.on_metal_emissive_map) + + self.ui.metal_light_map_lineEdit.textEdited.connect(self.on_metal_light_map) + + self.ui.metal_uv_set_sp.valueChanged.connect(self.on_metal_uv_set) + + self.ui.metal_normal_map_lineEdit.textEdited.connect(self.on_metal_normal_map) + self.ui.metal_normal_map_type_comboBox.currentTextChanged.connect(self.on_metal_normal_map_type) + + #specular + #elements under the specular subelement + specular=self._material_element.find(".//pbr/specular") + self.ui.specular_albedo_map_lineEdit.textEdited.connect(self.on_specular_albdedo_map) + + self.ui.specular_map_lineEdit.textEdited.connect(self.on_specular_map) + + self.ui.specular_glossiness_sp.valueChanged.connect(self.on_specular_glossiness) + + self.ui.specular_environment_map_lineEdit.textEdited.connect(self.on_specular_environment_map) + self.ui.specular_ambient_occlusion_map_lineEdit.textEdited.connect(self.on_specular_ambient_occlusion_map) + self.ui.specular_emissive_map_lineEdit.textEdited.connect(self.on_specular_emissive_map) + self.ui.specular_glossiness_map_lineEdit.textEdited.connect(self.on_specular_glossiness_map) + self.ui.specular_light_map_lineEdit.textEdited.connect(self.on_specular_light_map) + + self.ui.specular_uv_set_sp.valueChanged.connect(self.on_specular_uv_set) + + self.ui.specular_normal_map_lineEdit.textEdited.connect(self.on_specular_normal_map + ) + self.ui.specular_normal_map_type_comboBox.currentTextChanged.connect(self.on_specular_normal_map_type + ) + +#callbacks + #metal + def on_metal_albedo_map(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,'albedo_map',False,self.properties.metal_albedo_map) + + def on_metal_roughness_map(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,'roughness_map',False,self.properties.metal_roughness_map) + + def on_metal_roughness(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"roughness",False,self.properties.metal_roughness) + + + def on_metalness_map(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"metalness_map",False,self.properties.metalness_map) + + def on_metalness(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"metalness",False,self.properties.metalness) + + def on_metal_environment_map(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"environment_map",False,self.properties.metal_environment_map) + + def on_metal_ambient_occlusion_map(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"ambient_occlusion_map",False,self.properties.metal_ambient_occlusion_map) + + def on_metal_emissive_map(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"emissive_map",False,self.properties.metal_emissive_map) + + def on_metal_light_map(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"light_map",False,self.properties.metal_light_map) + + def on_metal_uv_set(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"light_map",True,{"uv_set":self.properties.metal_uv_set}) + + + def on_metal_normal_map(self): + metal=self._material_element.find(' common.set_xml_data(specular,"albedo_map",False,self.properties.specular_albedo_map).//pbr/metal') + common.set_xml_data(metal,"normal_map",False,self.properties.metal_normal_map) + + + def on_metal_normal_map_type(self): + metal=self._material_element.find('.//pbr/metal') + common.set_xml_data(metal,"normal_map",True,{"type":self.properties.metal_normal_map_type}) + + #specular + + def on_specular_albdedo_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"albedo_map",False,self.properties.specular_albedo_map) + + def on_specular_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"specular_map",False,self.properties.specular_map) + + def on_specular_glossiness(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"glossiness",False,self.properties.specular_glossiness) + + + def on_specular_environment_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"environment_map",False,self.properties.specular_environment_map) + + def on_specular_ambient_occlusion_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"ambient_occlusion_map",False,self.properties.specular_ambient_occlusion_map) + + def on_specular_emissive_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"emissive_map",False,self.properties.specular_emissive_map) + + def on_specular_glossiness_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"glossiness_map",False,self.properties.specular_glossiness_map) + + def on_specular_light_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"light_map",False,self.properties.specular_light_map) + + def on_specular_uv_set(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"light_map",True,{"uv_set":self.properties.specular_uv_set}) + + def on_specular_normal_map(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"normal_map",False,self.properties.specular_normal_map) + + def on_specular_normal_map_type(self): + specular=self._material_element.find(".//pbr/specular") + common.set_xml_data(specular,"normal_map",True,{"type":self.properties.specular_normal_map_type}) + + + def on_uri(self): + common.set_xml_data(self._material_element,'uri',False,self.properties.script_uri) + + def on_uri_name(self): + common.set_xml_data(self._material_element,'name',False,self.properties.script_name) + + def on_shader_type(self): + common.set_xml_data(self._material_element,'shader',True,{'type':self.properties.shader_type}) + + +#normal map + def on_normal_map(self): + common.set_xml_data(self._material_element,'normal_map',False,self.properties.normal_map) + +#material render order + def on_material_render_ord(self): + common.set_xml_data(self._material_element,'render_order',False,self.properties.render_order) + + def on_shininess(self): + common.set_xml_data(self._material_element,'shininess',False,self.properties.shininess) + + def on_ambient(self): + common.set_xml_data(self._material_element,'ambient',False,self.properties.ambient) + self.set_widget_color('ambient',self.ui.material_ambient_color_pkr) + + def on_diffuse(self): + common.set_xml_data(self._material_element,'diffuse',False,self.properties.diffuse) + self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr) + + def on_specular(self): + common.set_xml_data(self._material_element,'specular',False,self.properties.specular) + self.set_widget_color('specular',self.ui.material_specular_color_pkr) + + def on_emissive(self): + common.set_xml_data(self._material_element,'emissive',False,self.properties.emissive) + self.set_widget_color('emissive',self.ui.material_emissive_color_pkr) + + def on_ambient_color_pkr(self): + self.color_picker('ambient',self.ui.material_ambient_color_pkr) + + def on_diffuse_color_pkr(self): + self.color_picker('diffuse',self.ui.material_diffuse_color_pkr) + + def on_specular_color_pkr(self): + self.color_picker('specular',self.ui.material_specular_color_pkr) + + def on_emissive_color_pkr(self): + self.color_picker('emissive',self.ui.material_emissive_color_pkr) + + def updateUi(self): + self.properties.script_uri=common.get_xml_data(self._material_element,'uri',False) + self.properties.script_name=common.get_xml_data(self._material_element,'name',False) + self.properties.shader_type=common.get_xml_data(self._material_element,'type') + self.properties.normal_map=common.get_xml_data(self._material_element,'normal_map',False) + self.properties.render_order=common.get_xml_data(self._material_element,'render_order',False) + self.properties.shininess=common.get_xml_data(self._material_element,'shininess',False) + self.properties.ambient=common.get_xml_data(self._material_element,'ambient',False) + self.properties.diffuse=common.get_xml_data(self._material_element,'diffuse',False) + self.properties.specular=common.get_xml_data(self._material_element,'specular',False) + self.properties.emissive=common.get_xml_data(self._material_element,'emissive',False) + self.properties.lighting=common.get_xml_data(self._material_element,"lighting",False) + #pbr + #metal + metal=self._material_element.find('.//pbr/metal') + # { tag : property } + #properties is the property name defined in the properties class + items={'albedo_map':"metal_albedo_map",'roughness_map':"metal_roughness_map","metalness_map":"metalness_map","metalness":"metalness", + "environment_map":"metal_environment_map","ambient_occlusion_map":"metal_ambient_occlusion_map","emissive_map":"metal_emissive_map", + "light_map":"metal_light_map","normal_map":"metal_normal_map"} + #set the data for all items + for tag in items.keys(): + setattr(self.properties,items[tag],common.get_xml_data(metal,tag,False)) + #set element attributes + self.properties.metal_uv_set=common.get_xml_data(metal,["light_map","uv_set"],True) + self.properties.metal_normal_map_type=common.get_xml_data(metal,["normal_map","type"],True) + #specular + specular=self._material_element.find(".//pbr/specular") + #{tag : attribute} + specular_items={"albedo_map":"specular_albedo_map","specular_map":"specular_map","glossiness":"specular_glossiness","environment_map":"specular_environment_map", + "ambient_occlusion_map": "specular_ambient_occlusion_map","emissive_map":"specular_emissive_map","glossiness_map":"specular_glossiness_map", + "light_map":"specular_light_map","normal_map":"specular_normal_map"} + for tag in specular_items: + setattr(self.properties,specular_items[tag],common.get_xml_data(specular,tag,False)) + + self.properties.specular_uv_set=common.get_xml_data(specular,["light_map","uv_set"],True) + self.properties.specular_normal_map_type=common.get_xml_data(specular,["normal_map","type"],True) + + #style sheets + self.set_widget_color('ambient',self.ui.material_ambient_color_pkr) + self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr) + self.set_widget_color('specular',self.ui.material_specular_color_pkr) + self.set_widget_color('emissive',self.ui.material_emissive_color_pkr) + + def reset(self,default=True): + pass + + +#merger +#this merge method repeats alot + def merge_elements(self,destination_el, source_el): + common.merge_elements(destination_el,source_el) + + @property + def element(self): + #make deep copy to avoid altering local element + temp_el=copy.deepcopy(self._material_element) + #script + if self.ui.material_script_groupBox.isChecked(): + #if script is checked remove al other color properties + tags=['shader','ambient','diffuse','specular','emissive','shininess','render_order' + ,'lighting'] + for elem_tag in tags: + temp_el.remove(temp_el.find('.//'+elem_tag)) + else: + temp_el.remove(temp_el.find('.//script')) + #shader + if self.ui.material_shader_groupBox.isChecked(): + #if shader is checked check if the normal map is checked and remve it if neccessary + if self.properties.normal_map_checkbox is False: + shader_el=temp_el.find('.//shader') + shader_el.remove(shader_el.find('.//normal_map')) + + else: + temp_el.remove(temp_el.find('.//shader')) + + #remove color related configs + if self.ui.material_ambient_groupbox.isChecked() is False: + temp_el.remove(temp_el.find('.//ambient')) + + if self.ui.material_diffuse_groupbox.isChecked() is False: + temp_el.remove(temp_el.find('.//diffuse')) + + if self.ui.material_specular_groupbox.isChecked() is False: + temp_el.remove(temp_el.find('.//specular')) + + if self.ui.material_emissive_groupbox.isChecked() is False: + temp_el.remove(temp_el.find('.//emissive')) + + #logic for materials related to pbr + pbr=temp_el.find('pbr') + if self.properties.pbr_enabled and pbr is not None: + metal=temp_el.find('.//pbr/metal') + if self.properties.metal_enabled and metal is not None: + #{tag : property} + #where propertty are the propertieswhose names end with with _cb + metal_opt_elems={'albedo_map':"metal_albedo_map_cb",'roughness_map':"metal_roughness_map_cb","metalness_map":"metalness_map_cb" + ,"metalness":"metalness_cb", + "environment_map":"metal_environment_map_cb","ambient_occlusion_map":"metal_ambient_occlusion_map_cb","emissive_map":"metal_emissive_map_cb", + "light_map":"metal_light_map_cb","normal_map":"metal_normal_map_cb"} + for tag in metal_opt_elems.keys(): + if getattr(self.properties,metal_opt_elems[tag]) is not True: + metal.remove(metal.find('.//'+tag)) + else: + if metal is not None: + temp_el.find('.//pbr').remove(metal) + #related to specular + specular=temp_el.find(".//pbr/specular") + if self.properties.specular_enabled and specular is not None: + #{tag : property} + #where propertty are the properties whose names end with with _cb + specular_opts={"albedo_map":"specular_albedo_map_cb","specular_map":"specular_map_cb","glossiness":"specular_glossiness_cb", + "environment_map":"specular_environment_map_cb", + "ambient_occlusion_map": "specular_ambient_occlusion_map_cb","emissive_map":"specular_emissive_map_cb", + "glossiness_map":"specular_glossiness_map_cb", + "light_map":"specular_light_map_cb","normal_map":"specular_normal_map_cb"} + for tag in specular_opts.keys(): + if getattr(self.properties,specular_opts[tag]) is not True: + specular.remove(specular.find('.//'+tag)) + else: + if specular is not None: + temp_el.find('.//pbr').remove(specular) + else: + if pbr is not None: + temp_el.remove(pbr) + + return temp_el \ No newline at end of file diff --git a/robot_descriptor/sdf_elements/model.py b/robot_descriptor/sdf_elements/model.py new file mode 100644 index 0000000..a75a114 --- /dev/null +++ b/robot_descriptor/sdf_elements/model.py @@ -0,0 +1,9 @@ +from ..RD_utils import initialize_element_tree + + +class model: + def __intit__(self,root_d): + self.file_name='model.sdf' + self.parent_path=['sdf'] + self._root_dict=root_d + self.model_element=initialize_element_tree.convdict_2_tree(self.file_name) \ No newline at end of file diff --git a/robot_descriptor/sdf_elements/physics.py b/robot_descriptor/sdf_elements/physics.py index 9f91fd8..ebf620e 100644 --- a/robot_descriptor/sdf_elements/physics.py +++ b/robot_descriptor/sdf_elements/physics.py @@ -1,7 +1,7 @@ import xml.etree.ElementTree as ET -from ..RD_parser import initialize_element_tree -from .. import RD_globals +from ..RD_utils import initialize_element_tree +from .. import common import copy from PySide import QtCore @@ -394,67 +394,67 @@ def configUI(self): #callbacks def on_type(self): - RD_globals.set_xml_data(self._ode_elem,"type",False,self.solver.type) + common.set_xml_data(self._ode_elem,"type",False,self.solver.type) def on_min_step_size(self): - RD_globals.set_xml_data(self._ode_elem,"min_step_size",False,self.solver.min_step_size) + common.set_xml_data(self._ode_elem,"min_step_size",False,self.solver.min_step_size) def on_island_threads(self): - RD_globals.set_xml_data(self._ode_elem,"island_threads",False,self.solver.island_threads) + common.set_xml_data(self._ode_elem,"island_threads",False,self.solver.island_threads) def on_friction_model(self): - RD_globals.set_xml_data(self._ode_elem,"friction_model",False,self.solver.friction_model) + common.set_xml_data(self._ode_elem,"friction_model",False,self.solver.friction_model) def on_iters(self): - RD_globals.set_xml_data(self._ode_elem,"iters",False,self.solver.iters) + common.set_xml_data(self._ode_elem,"iters",False,self.solver.iters) def on_precon_iters(self): - RD_globals.set_xml_data(self._ode_elem,"precon_iters",False,self.solver.precon_iters) + common.set_xml_data(self._ode_elem,"precon_iters",False,self.solver.precon_iters) def on_sor(self): - RD_globals.set_xml_data(self._ode_elem,"sor",False,self.solver.sor) + common.set_xml_data(self._ode_elem,"sor",False,self.solver.sor) def on_dynamic_moi_rescaling(self): - RD_globals.set_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False,self.solver.use_dynamic_moi_rescaling) + common.set_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False,self.solver.use_dynamic_moi_rescaling) def on_thread_position_correction(self): - RD_globals.set_xml_data(self._ode_elem,"thread_position_correction",False,self.solver.thread_position_correction) + common.set_xml_data(self._ode_elem,"thread_position_correction",False,self.solver.thread_position_correction) def on_cfm(self): - RD_globals.set_xml_data(self._ode_elem,"cfm",False,self.constraints.cfm) + common.set_xml_data(self._ode_elem,"cfm",False,self.constraints.cfm) def on_erp(self): - RD_globals.set_xml_data(self._ode_elem,"erp",False,self.constraints.erp) + common.set_xml_data(self._ode_elem,"erp",False,self.constraints.erp) def on_contact_max_correction_vel(self): - RD_globals.set_xml_data(self._ode_elem,"contact_max_correcting_vel",False,self.constraints.contact_max_correcting_vel) + common.set_xml_data(self._ode_elem,"contact_max_correcting_vel",False,self.constraints.contact_max_correcting_vel) def on_contact_surface_layer(self): - RD_globals.set_xml_data(self._ode_elem,"contact_surface_layer",False,self.constraints.contact_surface_layer) + common.set_xml_data(self._ode_elem,"contact_surface_layer",False,self.constraints.contact_surface_layer) #end callbacks def update_ui(self): #solver - self.solver.type=RD_globals.get_xml_data(self._ode_elem,"type",False) - self.solver.min_step_size=float(RD_globals.get_xml_data(self._ode_elem,"min_step_size",False)) - self.solver.island_threads=int(RD_globals.get_xml_data(self._ode_elem,"island_threads",False)) - self.solver.iters=float(RD_globals.get_xml_data(self._ode_elem,"iters",False)) - self.solver.precon_iters=int(RD_globals.get_xml_data(self._ode_elem,"precon_iters",False)) - self.solver.sor=float(RD_globals.get_xml_data(self._ode_elem,"sor",False)) - self.solver.friction_model=RD_globals.get_xml_data(self._ode_elem,"friction_model",False) - - if RD_globals.get_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False)=='true': + self.solver.type=common.get_xml_data(self._ode_elem,"type",False) + self.solver.min_step_size=float(common.get_xml_data(self._ode_elem,"min_step_size",False)) + self.solver.island_threads=int(common.get_xml_data(self._ode_elem,"island_threads",False)) + self.solver.iters=float(common.get_xml_data(self._ode_elem,"iters",False)) + self.solver.precon_iters=int(common.get_xml_data(self._ode_elem,"precon_iters",False)) + self.solver.sor=float(common.get_xml_data(self._ode_elem,"sor",False)) + self.solver.friction_model=common.get_xml_data(self._ode_elem,"friction_model",False) + + if common.get_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False)=='true': self.solver.use_dynamic_moi_rescaling=True else: self.solver.use_dynamic_moi_rescaling=False - if RD_globals.get_xml_data(self._ode_elem,"thread_position_correction",False)=='true': + if common.get_xml_data(self._ode_elem,"thread_position_correction",False)=='true': self.solver.thread_position_correction=True else: self.solver.thread_position_correction=False #constraints - self.constraints.cfm=float(RD_globals.get_xml_data(self._ode_elem,"cfm",False)) - self.constraints.erp=float(RD_globals.get_xml_data(self._ode_elem,"erp")) - self.constraints.contact_max_correcting_vel=float(RD_globals.get_xml_data(self._ode_elem,"contact_max_correcting_vel")) - self.constraints.contact_surface_layer=float(RD_globals.get_xml_data(self._ode_elem,"contact_surface_layer")) + self.constraints.cfm=float(common.get_xml_data(self._ode_elem,"cfm",False)) + self.constraints.erp=float(common.get_xml_data(self._ode_elem,"erp")) + self.constraints.contact_max_correcting_vel=float(common.get_xml_data(self._ode_elem,"contact_max_correcting_vel")) + self.constraints.contact_surface_layer=float(common.get_xml_data(self._ode_elem,"contact_surface_layer")) #this takes an element and updates the internal ones def reset(self,new_elem:ET.Element): self._get_ode_elem(new_elem) @@ -495,45 +495,45 @@ def configUI(self): self.ui.bullet_split_impulse_penetration_threshold.valueChanged.connect(self.on_splt_impl_pen_tr) #solver def on_type(self): - RD_globals.set_xml_data(self._bullet_element,"solver",False,self.solver.type) + common.set_xml_data(self._bullet_element,"solver",False,self.solver.type) def on_min_step_size(self): - RD_globals.set_xml_data(self._bullet_element,"min_step_size",False,self.solver.min_step_size) + common.set_xml_data(self._bullet_element,"min_step_size",False,self.solver.min_step_size) def on_iters(self): - RD_globals.set_xml_data(self._bullet_element,"iters",False,self.solver.iters) + common.set_xml_data(self._bullet_element,"iters",False,self.solver.iters) def on_sor(self): - RD_globals.set_xml_data(self._bullet_element,"sor",False,self.solver.sor) + common.set_xml_data(self._bullet_element,"sor",False,self.solver.sor) #constraints def on_cfm(self): - RD_globals.set_xml_data(self._bullet_element,"cfm",False,self.constraints.cfm) + common.set_xml_data(self._bullet_element,"cfm",False,self.constraints.cfm) def on_erp(self): - RD_globals.set_xml_data(self._bullet_element,"erp",False,self.constraints.erp) + common.set_xml_data(self._bullet_element,"erp",False,self.constraints.erp) def on_cont_surf_layer(self): - RD_globals.set_xml_data(self._bullet_element,"contact_surface_layer",False,self.constraints.contact_surface_layer) + common.set_xml_data(self._bullet_element,"contact_surface_layer",False,self.constraints.contact_surface_layer) def on_split_impulse(self): - RD_globals.set_xml_data(self._bullet_element,"split_impulse",False,self.constraints.split_impulse) + common.set_xml_data(self._bullet_element,"split_impulse",False,self.constraints.split_impulse) def on_splt_impl_pen_tr(self): - RD_globals.set_xml_data(self._bullet_element,"split_impulse_penetration_threshold",False,self.constraints.split_impulse_penetration_threshold) + common.set_xml_data(self._bullet_element,"split_impulse_penetration_threshold",False,self.constraints.split_impulse_penetration_threshold) def update_ui(self): #solver ui - self.solver.type=RD_globals.get_xml_data(self._bullet_element,"type",False) - self.solver.min_step_size=float(RD_globals.get_xml_data(self._bullet_element,"min_step_size",False)) - self.solver.iters=int(RD_globals.get_xml_data(self._bullet_element,"iters",False)) - self.solver.sor=float(RD_globals.get_xml_data(self._bullet_element,"sor",False)) + self.solver.type=common.get_xml_data(self._bullet_element,"type",False) + self.solver.min_step_size=float(common.get_xml_data(self._bullet_element,"min_step_size",False)) + self.solver.iters=int(common.get_xml_data(self._bullet_element,"iters",False)) + self.solver.sor=float(common.get_xml_data(self._bullet_element,"sor",False)) #constrains ui - self.constraints.cfm=float(RD_globals.get_xml_data(self._bullet_element,"cfm",False)) - self.constraints.erp=float(RD_globals.get_xml_data(self._bullet_element,"erp",False)) - self.constraints.contact_surface_layer=float(RD_globals.get_xml_data(self._bullet_element,"contact_surface_layer")) - self.constraints.split_impulse_penetration_threshold=float(RD_globals.get_xml_data(self._bullet_element, + self.constraints.cfm=float(common.get_xml_data(self._bullet_element,"cfm",False)) + self.constraints.erp=float(common.get_xml_data(self._bullet_element,"erp",False)) + self.constraints.contact_surface_layer=float(common.get_xml_data(self._bullet_element,"contact_surface_layer")) + self.constraints.split_impulse_penetration_threshold=float(common.get_xml_data(self._bullet_element, "split_impulse_penetration_threshold")) - if RD_globals.get_xml_data(self._bullet_element,"split_impulse")=='true': + if common.get_xml_data(self._bullet_element,"split_impulse")=='true': self.constraints.split_impulse=True else: self.constraints.split_impulse=False @@ -579,58 +579,58 @@ def configUI(self): #callbacks #properties def on_min_step_size(self): - RD_globals.set_xml_data(self._simbody_element,"min_step_size",False,self.properties.min_step_size) + common.set_xml_data(self._simbody_element,"min_step_size",False,self.properties.min_step_size) def on_accuracy(self): - RD_globals.set_xml_data(self._simbody_element,"accuracy",False,self.properties.accuracy) + common.set_xml_data(self._simbody_element,"accuracy",False,self.properties.accuracy) def on_max_trans_vel(self): - RD_globals.set_xml_data(self._simbody_element,"max_transient_velocity",False,self.properties.maximum_transient_velocity) + common.set_xml_data(self._simbody_element,"max_transient_velocity",False,self.properties.maximum_transient_velocity) #contact def on_stiffness(self): - RD_globals.set_xml_data(self._simbody_element,"stiffness",False,self.contact.stiffness) + common.set_xml_data(self._simbody_element,"stiffness",False,self.contact.stiffness) def on_plst_coef_rest(self): - RD_globals.set_xml_data(self._simbody_element,"plastic_coef_restitution",False,self.contact.plastic_coef_restitution) + common.set_xml_data(self._simbody_element,"plastic_coef_restitution",False,self.contact.plastic_coef_restitution) def on_plst_imp_vel(self): - RD_globals.set_xml_data(self._simbody_element,"plastic_impact_velocity",False,self.contact.plastic_impact_velocity) + common.set_xml_data(self._simbody_element,"plastic_impact_velocity",False,self.contact.plastic_impact_velocity) def on_ovr_imp_cpt_vel(self): - RD_globals.set_xml_data(self._simbody_element,"override_impact_capture_velocity",False,self.contact.override_impact_capture_velocity) + common.set_xml_data(self._simbody_element,"override_impact_capture_velocity",False,self.contact.override_impact_capture_velocity) def on_dissipation(self): - RD_globals.set_xml_data(self._simbody_element,"dissipation",False,self.contact.dissipation) + common.set_xml_data(self._simbody_element,"dissipation",False,self.contact.dissipation) def on_static_fric(self): - RD_globals.set_xml_data(self._simbody_element,"static_friction",False,self.contact.static_friction) + common.set_xml_data(self._simbody_element,"static_friction",False,self.contact.static_friction) def on_dyn_fric(self): - RD_globals.set_xml_data(self._simbody_element,"dynamic_friction",False,self.contact.dynamic_friction) + common.set_xml_data(self._simbody_element,"dynamic_friction",False,self.contact.dynamic_friction) def on_vsc_fric(self): - RD_globals.set_xml_data(self._simbody_element,"viscous_friction",False,self.contact.viscous_friction) + common.set_xml_data(self._simbody_element,"viscous_friction",False,self.contact.viscous_friction) def on_ovr_st_tr_vel(self): - RD_globals.set_xml_data(self._simbody_element,"override_stiction_transition_velocity",False,self.contact.override_stiction_transition_velocity) + common.set_xml_data(self._simbody_element,"override_stiction_transition_velocity",False,self.contact.override_stiction_transition_velocity) #update ui def update_ui(self): #properties - self.properties.min_step_size=float(RD_globals.get_xml_data(self._simbody_element,"min_step_size",False)) - self.properties.accuracy=float(RD_globals.get_xml_data(self._simbody_element,"accuracy",False)) - self.properties.maximum_transient_velocity=float(RD_globals.get_xml_data(self._simbody_element,"max_transient_velocity",False)) + self.properties.min_step_size=float(common.get_xml_data(self._simbody_element,"min_step_size",False)) + self.properties.accuracy=float(common.get_xml_data(self._simbody_element,"accuracy",False)) + self.properties.maximum_transient_velocity=float(common.get_xml_data(self._simbody_element,"max_transient_velocity",False)) #contact - self.contact.stiffness=float(RD_globals.get_xml_data(self._simbody_element,"stiffness",False)) - self.contact.plastic_coef_restitution=float(RD_globals.get_xml_data(self._simbody_element,"plastic_coef_restitution",False)) - self.contact.plastic_impact_velocity=float(RD_globals.get_xml_data(self._simbody_element,"plastic_impact_velocity",False)) - self.contact.override_impact_capture_velocity=float(RD_globals.get_xml_data(self._simbody_element,"override_impact_capture_velocity",False)) - self.contact.dissipation=float(RD_globals.get_xml_data(self._simbody_element,"dissipation",False)) - self.contact.static_friction=float(RD_globals.get_xml_data(self._simbody_element,"static_friction",False)) - self.contact.dynamic_friction=float(RD_globals.get_xml_data(self._simbody_element,"dynamic_friction",False)) - self.contact.viscous_friction=float(RD_globals.get_xml_data(self._simbody_element,"viscous_friction",False)) - self.contact.override_stiction_transition_velocity=float(RD_globals.get_xml_data(self._simbody_element,"override_stiction_transition_velocity",False)) + self.contact.stiffness=float(common.get_xml_data(self._simbody_element,"stiffness",False)) + self.contact.plastic_coef_restitution=float(common.get_xml_data(self._simbody_element,"plastic_coef_restitution",False)) + self.contact.plastic_impact_velocity=float(common.get_xml_data(self._simbody_element,"plastic_impact_velocity",False)) + self.contact.override_impact_capture_velocity=float(common.get_xml_data(self._simbody_element,"override_impact_capture_velocity",False)) + self.contact.dissipation=float(common.get_xml_data(self._simbody_element,"dissipation",False)) + self.contact.static_friction=float(common.get_xml_data(self._simbody_element,"static_friction",False)) + self.contact.dynamic_friction=float(common.get_xml_data(self._simbody_element,"dynamic_friction",False)) + self.contact.viscous_friction=float(common.get_xml_data(self._simbody_element,"viscous_friction",False)) + self.contact.override_stiction_transition_velocity=float(common.get_xml_data(self._simbody_element,"override_stiction_transition_velocity",False)) @property def element(self): @@ -657,14 +657,14 @@ def configUI(self): self.ui.dart_collison_detector.currentTextChanged.connect(self.on_collision) #callbacks def on_type(self): - RD_globals.set_xml_data(self._dart_element,"solver_type",False,self.properties.solver_type) + common.set_xml_data(self._dart_element,"solver_type",False,self.properties.solver_type) def on_collision(self): - RD_globals.set_xml_data(self._dart_element,"collision_detector",False,self.properties.collision_detector) + common.set_xml_data(self._dart_element,"collision_detector",False,self.properties.collision_detector) def update_ui(self): - self.properties.solver_type=RD_globals.get_xml_data(self._dart_element,"solver_type",False) - self.properties.collision_detector=RD_globals.get_xml_data(self._dart_element,"collision_detector",False) + self.properties.solver_type=common.get_xml_data(self._dart_element,"solver_type",False) + self.properties.collision_detector=common.get_xml_data(self._dart_element,"collision_detector",False) @property def element(self): return self._dart_element @@ -781,22 +781,22 @@ def on_reset(self): print("physics resets applied \n") def on_step_sz(self): - RD_globals.set_xml_data(self._physics_elem,"max_step_size",False,self.properties.max_step_size) + common.set_xml_data(self._physics_elem,"max_step_size",False,self.properties.max_step_size) def on_real_time_fct(self): - RD_globals.set_xml_data(self._physics_elem,"real_time_factor",False,self.properties.real_time_factor) + common.set_xml_data(self._physics_elem,"real_time_factor",False,self.properties.real_time_factor) def on_update_rt(self): - RD_globals.set_xml_data(self._physics_elem,"real_time_update_rate",False,self.properties.real_time_update_rate) + common.set_xml_data(self._physics_elem,"real_time_update_rate",False,self.properties.real_time_update_rate) def on_max_cnt(self): - RD_globals.set_xml_data(self._physics_elem,"max_contacts",False,self.properties.max_contacts) + common.set_xml_data(self._physics_elem,"max_contacts",False,self.properties.max_contacts) #ode radio button def on_ode_radio_button(self): self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__()) self.current_type_tag="ode" - RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) + common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) self._physics_elem.append(self._ode.element) #ode is at index 0 self.ui.physics_type_stack.setCurrentIndex(0) @@ -805,7 +805,7 @@ def on_ode_radio_button(self): def on_bullet_radio_button(self): self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__()) self.current_type_tag="bullet" - RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) + common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) self._physics_elem.append(self._bullet.element) #bullet is at index 1 self.ui.physics_type_stack.setCurrentIndex(1) @@ -815,7 +815,7 @@ def on_simbody_radio_button(self): #remove current element self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__()) self.current_type_tag="simbody" - RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) + common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) self._physics_elem.append(self._simbody.element) #simbody is at index 2 self.ui.physics_type_stack.setCurrentIndex(2) @@ -825,17 +825,17 @@ def on_dart_radio_button(self): #remove current element self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__()) self.current_type_tag="dart" - RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) + common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag}) self._physics_elem.append(self._dart.element) #dart is at index 3 self.ui.physics_type_stack.setCurrentIndex(3) def update_ui(self): - self.properties.max_contacts=int(RD_globals.get_xml_data(self._physics_elem,"max_contacts",False)) - self.properties.real_time_update_rate=float(RD_globals.get_xml_data(self._physics_elem,"real_time_update_rate",False)) - self.properties.real_time_factor=float(RD_globals.get_xml_data(self._physics_elem,"real_time_factor",False)) - self.properties.max_step_size=float(RD_globals.get_xml_data(self._physics_elem,"max_step_size")) + self.properties.max_contacts=int(common.get_xml_data(self._physics_elem,"max_contacts",False)) + self.properties.real_time_update_rate=float(common.get_xml_data(self._physics_elem,"real_time_update_rate",False)) + self.properties.real_time_factor=float(common.get_xml_data(self._physics_elem,"real_time_factor",False)) + self.properties.max_step_size=float(common.get_xml_data(self._physics_elem,"max_step_size")) def reset(self,default:bool=True): @@ -853,7 +853,7 @@ def reset(self,default:bool=True): else: doc=FreeCAD.ActiveDocument _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag]) + el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag]) if el_dict is not None: el_str=el_dict['elem_str'] diff --git a/robot_descriptor/sdf_elements/road.py b/robot_descriptor/sdf_elements/road.py index 26055e8..19f1259 100644 --- a/robot_descriptor/sdf_elements/road.py +++ b/robot_descriptor/sdf_elements/road.py @@ -1,398 +1,109 @@ -from ..import RD_globals -from ..RD_parser import initialize_element_tree -import copy -from PySide import QtGui,QtCore -import re +from .. import common +from ..RD_utils import initialize_element_tree +import copy +from PySide import QtGui, QtCore +import re import math import csv + # import Spreadsheet import os -import xml.etree.ElementTree as ET -import FreeCAD -#======================================== -#road properties -#======================================== +import xml.etree.ElementTree as ET +import FreeCAD, FreeCADGui + + +# ======================================== +# road properties +# ======================================== class road_properties: - def __init__(self,ui) -> None: - self.ui=ui -#name property + def __init__(self, ui) -> None: + self.ui = ui + + # name property @property def name(self): return self.ui.road_name.text() + @name.setter - def name(self,text): + def name(self, text): self.ui.road_name.setText(text) -#width + # width @property def width(self): return self.ui.road_width_sp.value() + @width.setter - def width(self,value): + def width(self, value): self.ui.road_width_sp.setValue(value) - -#================================================== -# road material -#================================================== -class material_properties: - def __init__(self,ui) -> None: - self.ui=ui -#script uri - @property - def script_uri(self): - return self.ui.material_script_uri_input.text() - @script_uri.setter - def script_uri(self,text): - self.ui.material_script_uri_input.setText(text) - -#script name - @property - def script_name(self): - return self.ui.material_script_name.text() - @script_name.setter - def script_name(self,text): - self.ui.material_script_name.setText(text) - -#shader_type - @property - def shader_type(self): - return self.ui.shader_type.currentText() - @shader_type.setter - def shader_type(self,text): - self.ui.shader_type.setCurrentText(text) -#normal map - @property - def normal_map(self): - return self.ui.material_normal_map_input.text() - @normal_map.setter - def normal_map(self,text): - self.ui.material_normal_map_input.setText(text) - -#this checkebox is not part of the sdf data its just used to enable and disable the normal_map input -# so no need to convert bool to strinf - @property - def normal_map_checkbox(self): - return self.ui.normal_map_checkBox.isChecked() - - @normal_map_checkbox.setter - def normal_map_checkbox(self,state): - if state is True: - self.ui.normal_map_checkBox.setState(QtCore.Qt.Checked) - else: - self.ui.normal_map_checkBox.setState(QtCore.Qt.Unchecked) - -#render order - @property - def render_order(self): - return self.ui.material_render_order_sp.value() - @render_order.setter - def render_order(self,value): - self.ui.material_render_order_sp.setValue(value) -#shininess - @property - def shininess(self): - return self.ui.materroad_pointsial_shininess_sp.value() - @shininess.setter - def shininess(self,value): - self.ui.material_shininess_sp.setValue(value) - -#lighting - @property - def lighting(self): - state= self.ui.material_lighting_checkbox.isChecked() - if state is True: - return str('true') - else: - return str('false') - @lighting.setter - def lighting(self,state): - if state is True: - self.ui.material_lighting_checkbox.setState(QtCore.Qt.Checked) - else: - self.ui.material_lighting_checkbox.setState(QtCore.Qt.Unchecked) - - -#ambient - @property - def ambient(self): - return [self.ui.material_ambient_R_sp.value(),self.ui.material_ambient_G_sp.value(), - self.ui.material_ambient_B_sp.value(),self.ui.material_ambient_A_sp.value()] - @ambient.setter - def ambient(self,vals): - self.ui.material_ambient_R_sp.setValue(vals[0]) - self.ui.material_ambient_G_sp.setValue(vals[1]) - self.ui.material_ambient_B_sp.setValue(vals[2]) - self.ui.material_ambient_A_sp.setValue(vals[3]) -#diffuse - @property - def diffuse(self): - return [self.ui.material_diffuse_R_sp.value(),self.ui.material_diffuse_G_sp.value(), - self.ui.material_diffuse_B_sp.value(),self.ui.material_diffuse_A_sp.value()] - @diffuse.setter - def diffuse(self,vals): - self.ui.material_diffuse_R_sp.setValue(vals[0]) - self.ui.material_diffuse_G_sp.setValue(vals[1]) - self.ui.material_diffuse_B_sp.setValue(vals[2]) - self.ui.material_diffuse_A_sp.setValue(vals[3]) -#specular - @property - def specular(self): - return [self.ui.material_specular_R_sp.value(),self.ui.material_specular_G_sp.value(), - self.ui.material_specular_B_sp.value(),self.ui.material_specular_A_sp.value()] - @specular.setter - def specular(self,vals): - self.ui.material_specular_R_sp.setValue(vals[0]) - self.ui.material_specular_G_sp.setValue(vals[1]) - self.ui.material_specular_B_sp.setValue(vals[2]) - self.ui.material_specular_A_sp.setValue(vals[3]) -#emissive - @property - def emissive(self): - return [self.ui.material_emissive_R_sp.value(),self.ui.material_emissive_G_sp.value(), - self.ui.material_emissive_B_sp.value(),self.ui.material_emissive_A_sp.value()] - @emissive.setter - def emissive(self,vals): - self.ui.material_emissive_R_sp.setValue(vals[0]) - self.ui.material_emissive_G_sp.setValue(vals[1]) - self.ui.material_emissive_B_sp.setValue(vals[2]) - self.ui.material_emissive_A_sp.setValue(vals[3]) +# ================================================= +# ================================================= +# road +# ================================================== +# ================================================= +from . import material -#=========================================== -#=========================================== -#material element -#============================================ -#============================================ -class material(RD_globals.color_pickr): - def __init__(self,ui) -> None: - super().__init__() - self.ui=ui - #use the road tag since material will be implemented as part of the road element - self.tag='road' - self.parent_path=['sdf','world'] - self.file_name='material.sdf' - self._material_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element - self.properties=material_properties(self.ui) - #remove unused material elements - self._material_element.remove(self._material_element.find('.//pbr')) - self._material_element.remove(self._material_element.find('.//double_sided')) - self.configUI() - self.reset(default=False) - - def configUI(self): - self.ui.material_script_uri_input.textEdited.connect(self.on_uri) - self.ui.material_script_name.textEdited.connect(self.on_uri_name) - self.ui.shader_type.currentTextChanged.connect(self.on_shader_type) - self.ui.normal_map_checkBox.stateChanged.connect(self.on_normal_map_state) - self.ui.material_normal_map_input.textEdited.connect(self.on_normal_map) - self.ui.material_render_order_sp.valueChanged.connect(self.on_material_render_ord) - self.ui.material_shininess_sp.valueChanged.connect(self.on_shininess) - - #ambient - self.ui.material_ambient_R_sp.valueChanged.connect(self.on_ambient) - self.ui.material_ambient_G_sp.valueChanged.connect(self.on_ambient) - self.ui.material_ambient_B_sp.valueChanged.connect(self.on_ambient) - self.ui.material_ambient_A_sp.valueChanged.connect(self.on_ambient) - #diffuse - self.ui.material_diffuse_R_sp.valueChanged.connect(self.on_diffuse) - self.ui.material_diffuse_G_sp.valueChanged.connect(self.on_diffuse) - self.ui.material_diffuse_B_sp.valueChanged.connect(self.on_diffuse) - self.ui.material_diffuse_A_sp.valueChanged.connect(self.on_diffuse) - #specular - self.ui.material_specular_R_sp.valueChanged.connect(self.on_specular) - self.ui.material_specular_G_sp.valueChanged.connect(self.on_specular) - self.ui.material_specular_B_sp.valueChanged.connect(self.on_specular) - self.ui.material_specular_A_sp.valueChanged.connect(self.on_specular) - #emissive - self.ui.material_emissive_R_sp.valueChanged.connect(self.on_emissive) - self.ui.material_emissive_G_sp.valueChanged.connect(self.on_emissive) - self.ui.material_emissive_B_sp.valueChanged.connect(self.on_emissive) - self.ui.material_emissive_A_sp.valueChanged.connect(self.on_emissive) - - #color picker buttons - self.ui.material_ambient_color_pkr.clicked.connect(self.on_ambient_color_pkr) - self.ui.material_diffuse_color_pkr.clicked.connect(self.on_diffuse_color_pkr) - self.ui.material_specular_color_pkr.clicked.connect(self.on_specular_color_pkr) - self.ui.material_emissive_color_pkr.clicked.connect(self.on_emissive_color_pkr) - - - def on_uri(self): - RD_globals.set_xml_data(self._material_element,'uri',False,self.properties.script_uri) - - def on_uri_name(self): - RD_globals.set_xml_data(self._material_element,'name',False,self.properties.script_name) - - def on_shader_type(self): - RD_globals.set_xml_data(self._material_element,'shader',True,{'type':self.properties.shader_type}) - -#enable and disable normal map - def on_normal_map_state(self): - if self.properties.normal_map_checkbox: - self.ui.material_normal_map_input.setEnabled(True) - else: - self.ui.material_normal_map_input.setEnabled(False) - -#normal map - def on_normal_map(self): - RD_globals.set_xml_data(self._material_element,'normal_map',False,self.properties.normal_map) - -#material render order - def on_material_render_ord(self): - RD_globals.set_xml_data(self._material_element,'render_order',False,self.properties.render_order) - - def on_shininess(self): - RD_globals.set_xml_data(self._material_element,'shininess',False,self.properties.shininess) - - def on_ambient(self): - RD_globals.set_xml_data(self._material_element,'ambient',False,self.properties.ambient) - self.set_widget_color('ambient',self.ui.material_ambient_color_pkr) - - def on_diffuse(self): - RD_globals.set_xml_data(self._material_element,'diffuse',False,self.properties.diffuse) - self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr) - - def on_specular(self): - RD_globals.set_xml_data(self._material_element,'specular',False,self.properties.specular) - self.set_widget_color('specular',self.ui.material_specular_color_pkr) +class road_material(material.material): + def __init__(self, ui): + self.ui = ui - def on_emissive(self): - RD_globals.set_xml_data(self._material_element,'emissive',False,self.properties.emissive) - self.set_widget_color('emissive',self.ui.material_emissive_color_pkr) - - def on_ambient_color_pkr(self): - self.color_picker('ambient',self.ui.material_ambient_color_pkr) - - def on_diffuse_color_pkr(self): - self.color_picker('diffuse',self.ui.material_diffuse_color_pkr) - - def on_specular_color_pkr(self): - self.color_picker('specular',self.ui.material_specular_color_pkr) - - def on_emissive_color_pkr(self): - self.color_picker('emissive',self.ui.material_emissive_color_pkr) - - def updateUi(self): - self.properties.script_uri=RD_globals.get_xml_data(self._material_element,'uri',False) - self.properties.script_name=RD_globals.get_xml_data(self._material_element,'name',False) - self.properties.shader_type=RD_globals.get_xml_data(self._material_element,'type') - self.properties.normal_map=RD_globals.get_xml_data(self._material_element,'normal_map',False) - self.properties.render_order=RD_globals.get_xml_data(self._material_element,'render_order',False) - self.properties.shininess=RD_globals.get_xml_data(self._material_element,'shininess',False) - self.properties.ambient=RD_globals.get_xml_data(self._material_element,'ambient',False) - self.properties.diffuse=RD_globals.get_xml_data(self._material_element,'diffuse',False) - self.properties.specular=RD_globals.get_xml_data(self._material_element,'specular',False) - self.properties.emissive=RD_globals.get_xml_data(self._material_element,'emissive',False) - #style sheets - self.set_widget_color('ambient',self.ui.material_ambient_color_pkr) - self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr) - self.set_widget_color('specular',self.ui.material_specular_color_pkr) - self.set_widget_color('emissive',self.ui.material_emissive_color_pkr) - - def reset(self,default=True): + super().__init__(self.ui) + #redefine parent path + self.parent_path = ["sdf", "world", "road"] + self.reset(default=False) + + def reset(self, default=True): if default: - self._material_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element - #remove unused elements - self._material_element.remove(self._material_element.find('.//pbr')) - self._material_element.remove(self._material_element.find('.//double_sided')) + self._material_element = initialize_element_tree.convdict_2_tree( + self.file_name + ).get_element else: - doc=FreeCAD.ActiveDocument - _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag]) + doc = FreeCAD.ActiveDocument + _root_dict = doc.Robot_Description.Proxy.element_dict + # since material does not exist independently find the parent + el_dict = common.parse_dict(_root_dict, self.parent_path) if el_dict is not None: - #find the material element from road - elem=ET.fromstring(el_dict['elem_str']).find('.//material') - #make check since material might not always be included in the final element tree - # since its optional + # find the material element in parent element + elem = ET.fromstring(el_dict["elem_str"]).find(".//material") + # make check since material might not always be included in the final element tree + # since its optional if elem is not None: - self.merge_elements(self._material_element,elem) + self.merge_elements(self._material_element, elem) self.updateUi() - - -#merger -#this merge method repeats alot - def merge_elements(self,destination_el, source_el): - # Update attributes of destination_el with source_el - destination_el.attrib.update(source_el.attrib) - if source_el.text: - destination_el.text = source_el.text - # Merge child elements recursively - for child in source_el: - existing_el = destination_el.find(child.tag) - if existing_el is not None: - self.merge_elements(existing_el, child) # Recursively merge the existing element with the new one - else: - # If the element doesn't exist in destination, simply append it - # destination_el.append(child) - pass - - @property - def element(self): - #make deep copy to avoid altering local element - temp_el=copy.deepcopy(self._material_element) - #script - if self.ui.material_script_groupBox.isChecked(): - #if script is checked remove al other color properties - tags=['shader','ambient','diffuse','specular','emissive','shininess','render_order' - ,'lighting'] - for elem_tag in tags: - temp_el.remove(temp_el.find('.//'+elem_tag)) - else: - temp_el.remove(temp_el.find('.//script')) - #shader - if self.ui.material_shader_groupBox.isChecked(): - #if shader is checked check if the normal map is checked and remve it if neccessary - if self.properties.normal_map_checkbox is False: - shader_el=temp_el.find('.//shader') - shader_el.remove(shader_el.find('.//normal_map')) - - else: - temp_el.remove(temp_el.find('.//shader')) - - #remove color related configs - if self.ui.material_ambient_groupbox.isChecked() is False: - temp_el.remove(temp_el.find('.//ambient')) - - if self.ui.material_diffuse_groupbox.isChecked() is False: - temp_el.remove(temp_el.find('.//diffuse')) - - if self.ui.material_specular_groupbox.isChecked() is False: - temp_el.remove(temp_el.find('.//specular')) - - if self.ui.material_emissive_groupbox.isChecked() is False: - temp_el.remove(temp_el.find('.//emissive')) - - return temp_el - - - -#================================================= -#================================================= -#road -#================================================== -#================================================= -class road(): - def __init__(self,ui): - self.ui=ui - self.parent_path=['sdf','world'] - self.tag='road' - self.file_name='road.sdf' - self._road_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element - self._road_properties=road_properties(self.ui) - #material element - self._material=material(self.ui) - self.point_element=copy.deepcopy(self._road_element.find('.//point')) - #disable the scroll widget + + +class road: + def __init__(self, ui): + self.ui = ui + self.parent_path = ["sdf", "world"] + self.tag = "road" + self.file_name = "road.sdf" + self._road_element = initialize_element_tree.convdict_2_tree( + self.file_name + ).get_element + self._road_properties = road_properties(self.ui) + # material element + self.material_widget = FreeCADGui.PySideUic.loadUi( + os.path.join(common.UI_PATH, "material.ui") + ) + self._material = road_material(self.material_widget) + + # disable unused material ui elements + self.material_widget.material_pbr_groupbox.setEnabled(False) + self.material_widget.material_double_sided_checkBox.setEnabled(False) + self.point_element = copy.deepcopy(self._road_element.find(".//point")) + # disable the scroll widget + + self.ui.road_scroll.setWidget(self.material_widget.widget) self.ui.road_scroll.setEnabled(False) - - #remove elements that will not be edited - - #configure the Ui and callbacks + # configure the Ui and callbacks self.configUI() self.reset(default=False) - + def configUI(self): self.ui.road_name.textEdited.connect(self.on_road_name) self.ui.road_width_sp.valueChanged.connect(self.on_road_width) @@ -400,80 +111,103 @@ def configUI(self): self.ui.enable_road_checkbox.clicked.connect(self.on_road_checkbox) def on_road_checkbox(self): - state=self.ui.enable_road_checkbox.isChecked() + state = self.ui.enable_road_checkbox.isChecked() if state: self.ui.road_scroll.setEnabled(True) else: self.ui.road_scroll.setEnabled(False) - + def on_road_reset(self): self.reset(default=True) - print('road resets applied\n') - + print("road resets applied\n") + def on_road_name(self): - RD_globals.set_xml_data(self._road_element,'road',True,{'name':self._road_properties.name}) - + common.set_xml_data( + self._road_element, "road", True, {"name": self._road_properties.name} + ) + def on_road_width(self): - RD_globals.set_xml_data(self._road_element,'width',False,self._road_properties.width) - + common.set_xml_data( + self._road_element, "width", False, self._road_properties.width + ) + def get_sheet_data(self): - #get spread sheet with points data - sheet=FreeCAD.ActiveDocument.points - data_cells=sheet.getNonEmptyCells() - #ensure all point data is available since a vector 3 is required - #all filled cells need to be a multiple of 3 - if len(data_cells)%3 !=0: - FreeCAD.Console.PrintUserWarning("some data is missing \n points not updated\n") + # get spread sheet with points data + sheet = FreeCAD.ActiveDocument.points + data_cells = sheet.getNonEmptyCells() + # ensure all point data is available since a vector 3 is required + # all filled cells need to be a multiple of 3 + if len(data_cells) % 3 != 0: + FreeCAD.Console.PrintUserWarning( + "some data is missing \n points not updated\n" + ) else: - #remove all points previously available in the tree - for point in self._road_element.iter('point'): + # remove all points previously available in the tree + for point in self._road_element.iter("point"): self._road_element.remove(point) - #use list comprehension to extract spreadsheet items 3 at a time - #produces - #start from 3 since the first 3 are the labels - for row in [ [sheet.getContents(data_cells[i]), sheet.getContents(data_cells[i+1]), sheet.getContents(data_cells[i+2])] - for i in range(3,len(data_cells),3)]: - point=copy.deepcopy(self.point_element) - point.text=' '.join(map(str,row)) + # use list comprehension to extract spreadsheet items 3 at a time + # produces + # start from 3 since the first 3 are the labels + for row in [ + [ + sheet.getContents(data_cells[i]), + sheet.getContents(data_cells[i + 1]), + sheet.getContents(data_cells[i + 2]), + ] + for i in range(3, len(data_cells), 3) + ]: + point = copy.deepcopy(self.point_element) + point.text = " ".join(map(str, row)) self._road_element.append(point) - - + def updateUI(self): - self._road_properties.name=RD_globals.get_xml_data(self._road_element,['road','name'],True) - self._road_properties.width=RD_globals.get_xml_data(self._road_element,'width',False) - - - def reset(self,default=True): + self._road_properties.name = common.get_xml_data( + self._road_element, ["road", "name"], True + ) + self._road_properties.width = common.get_xml_data( + self._road_element, "width", False + ) + + def reset(self, default=True): if default: - self._road_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element + self._road_element = initialize_element_tree.convdict_2_tree( + self.file_name + ).get_element self._material.reset(default=True) - self._road_properties.point=None + self._road_properties.point = None else: - doc=FreeCAD.ActiveDocument - _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag]) + doc = FreeCAD.ActiveDocument + _root_dict = doc.Robot_Description.Proxy.element_dict + el_dict = common.parse_dict(_root_dict, self.parent_path + [self.tag]) if el_dict is not None: - elem=ET.fromstring(el_dict['elem_str']) - self._road_element=elem - #remove material from the element - mat=self._road_element.find('.//material') - #material is an optional element hence might not be included - + elem = ET.fromstring(el_dict["elem_str"]) + self._road_element = elem + # remove material from the element + mat = self._road_element.find(".//material") + # material is an optional element hence might not be included + if mat is not None: - self._road_element.remove(mat ) - self.updateUI() - + self._road_element.remove(mat) + self._material.reset(default=False) + + # remove unused material elements + self._material._material_element.remove( + self._material._material_element.find(".//pbr") + ) + self._material._material_element.remove( + self._material._material_element.find(".//double_sided") + ) + + self.updateUI() + @property def element(self): - #update data in sheet before export + # update data in sheet before export self.get_sheet_data() - - - _elem=copy.deepcopy(self._road_element) - #check if materialis enabled - if self.ui.road_material_groupbox.isChecked(): - mat_el=self._material.element + + _elem = copy.deepcopy(self._road_element) + # check if materialis enabled + if self.ui.include_material_info.isChecked(): + mat_el = self._material.element _elem.append(mat_el) return _elem - - diff --git a/robot_descriptor/sdf_elements/scene.py b/robot_descriptor/sdf_elements/scene.py index 3a99c0f..9908030 100644 --- a/robot_descriptor/sdf_elements/scene.py +++ b/robot_descriptor/sdf_elements/scene.py @@ -1,8 +1,8 @@ -from .. import RD_globals +from .. import common import copy import xml.etree.ElementTree as ET import FreeCAD -from ..RD_parser import initialize_element_tree +from ..RD_utils import initialize_element_tree from PySide import QtCore from PySide.QtGui import QColorDialog import math @@ -217,7 +217,7 @@ def fog_density(self,value): #============================================== #=============================================== -class scene(RD_globals.color_pickr): +class scene(common.color_pickr): def __init__(self,ui): self.ui=ui self.parent_path=['sdf','world'] @@ -329,91 +329,91 @@ def on_scene_ambient(self): self.set_widget_color('scene_ambient',self.ui.scene_ambient_color_pkr) def on_background(self): - RD_globals.set_xml_data(self._scene_element,"background",False,self.properties.background) + common.set_xml_data(self._scene_element,"background",False,self.properties.background) self.set_widget_color('background',self.ui.scene_background_color_pkr) def on_time(self): - RD_globals.set_xml_data(self._scene_element,"time",False,self.properties.time) + common.set_xml_data(self._scene_element,"time",False,self.properties.time) def on_sunrise(self): - RD_globals.set_xml_data(self._scene_element,"sunrise",False,self.properties.sunrise) + common.set_xml_data(self._scene_element,"sunrise",False,self.properties.sunrise) def on_sunset(self): - RD_globals.set_xml_data(self._scene_element,"sunset",False,self.properties.sunset) + common.set_xml_data(self._scene_element,"sunset",False,self.properties.sunset) def on_speed(self): - RD_globals.set_xml_data(self._scene_element,"speed",False,self.properties.speed) + common.set_xml_data(self._scene_element,"speed",False,self.properties.speed) def on_direction(self): - RD_globals.set_xml_data(self._scene_element,"direction",False,self.properties.direction) + common.set_xml_data(self._scene_element,"direction",False,self.properties.direction) def on_humidity(self): - RD_globals.set_xml_data(self._scene_element,"humidity",False,self.properties.humidity) + common.set_xml_data(self._scene_element,"humidity",False,self.properties.humidity) def on_cloud_ambient(self): #write to the ambient in clouds element - RD_globals.set_xml_data(self._scene_element.find("sky"),"ambient",False,self.properties.clouds_ambient) + common.set_xml_data(self._scene_element.find("sky"),"ambient",False,self.properties.clouds_ambient) self.set_widget_color('clouds_ambient',self.ui.cloud_ambient_color_pkr) def on_mean_size(self): - RD_globals.set_xml_data(self._scene_element,"mean_size",False,self.properties.mean_size) + common.set_xml_data(self._scene_element,"mean_size",False,self.properties.mean_size) def on_cube_map(self): - RD_globals.set_xml_data(self._scene_element,"cubemap_uri",False,self.properties.cubemap_uri) + common.set_xml_data(self._scene_element,"cubemap_uri",False,self.properties.cubemap_uri) def on_shadow(self): - RD_globals.set_xml_data(self._scene_element,"shadows",False,self.properties.shadows) + common.set_xml_data(self._scene_element,"shadows",False,self.properties.shadows) def on_grid(self): - RD_globals.set_xml_data(self._scene_element,"grid",False,self.properties.grid) + common.set_xml_data(self._scene_element,"grid",False,self.properties.grid) def on_origin_visual(self): - RD_globals.set_xml_data(self._scene_element,"origin_visual",False,self.properties.origin_visual) + common.set_xml_data(self._scene_element,"origin_visual",False,self.properties.origin_visual) def on_fog_color(self): - RD_globals.set_xml_data(self._scene_element,"color",False,self.properties.fog_color) + common.set_xml_data(self._scene_element,"color",False,self.properties.fog_color) self.set_widget_color('fog_color',self.ui.fog_color_picker_btn) def on_fog_type(self): - RD_globals.set_xml_data(self._scene_element,"type",False,self.properties.fog_type) + common.set_xml_data(self._scene_element,"type",False,self.properties.fog_type) def on_fog_start(self): - RD_globals.set_xml_data(self._scene_element,"start",False,self.properties.fog_start) + common.set_xml_data(self._scene_element,"start",False,self.properties.fog_start) def on_fog_end(self): - RD_globals.set_xml_data(self._scene_element,"end",False,self.properties.fog_end) + common.set_xml_data(self._scene_element,"end",False,self.properties.fog_end) def on_fog_density(self): - RD_globals.set_xml_data(self._scene_element,"density",False,self.properties.fog_density) + common.set_xml_data(self._scene_element,"density",False,self.properties.fog_density) #callbacks #end def update_ui(self): - self.properties.scene_ambient=RD_globals.extract_vector_n(self._scene_element.find("ambient").text) + self.properties.scene_ambient=common.extract_vector_n(self._scene_element.find("ambient").text) - self.properties.background=RD_globals.get_xml_data(self._scene_element,"background",False) + self.properties.background=common.get_xml_data(self._scene_element,"background",False) - self.properties.time=float(RD_globals.get_xml_data(self._scene_element,"time",False)) - self.properties.sunrise=float(RD_globals.get_xml_data(self._scene_element,"sunrise",False)) - self.properties.sunset=float(RD_globals.get_xml_data(self._scene_element,"sunset",False)) - self.properties.speed=float(RD_globals.get_xml_data(self._scene_element,"speed",False)) - self.properties.direction=float(RD_globals.get_xml_data(self._scene_element,"direction",False)) - self.properties.humidity=float(RD_globals.get_xml_data(self._scene_element,"humidity",False)) - - self.properties.clouds_ambient=RD_globals.get_xml_data(self._scene_element.find("sky"),"ambient",False) - self.properties.mean_size=RD_globals.get_xml_data(self._scene_element,"mean_size",False) + self.properties.time=float(common.get_xml_data(self._scene_element,"time",False)) + self.properties.sunrise=float(common.get_xml_data(self._scene_element,"sunrise",False)) + self.properties.sunset=float(common.get_xml_data(self._scene_element,"sunset",False)) + self.properties.speed=float(common.get_xml_data(self._scene_element,"speed",False)) + self.properties.direction=float(common.get_xml_data(self._scene_element,"direction",False)) + self.properties.humidity=float(common.get_xml_data(self._scene_element,"humidity",False)) + + self.properties.clouds_ambient=common.get_xml_data(self._scene_element.find("sky"),"ambient",False) + self.properties.mean_size=common.get_xml_data(self._scene_element,"mean_size",False) - self.properties.cubemap_uri=RD_globals.get_xml_data(self._scene_element,"cubemap_uri",False) - self.properties.shadows=RD_globals.get_xml_data(self._scene_element,"shadows",False) - self.properties.grid=RD_globals.get_xml_data(self._scene_element,"grid",False) - self.properties.origin_visual=RD_globals.get_xml_data(self._scene_element,"origin_visual",False) - self.properties.fog_color=RD_globals.get_xml_data(self._scene_element,"color",False) - self.properties.fog_type=RD_globals.get_xml_data(self._scene_element,"type",False) - self.properties.fog_start=RD_globals.get_xml_data(self._scene_element,"start",False) - self.properties.fog_end=RD_globals.get_xml_data(self._scene_element,"end",False) - self.properties.fog_density=RD_globals.get_xml_data(self._scene_element,"density",False) + self.properties.cubemap_uri=common.get_xml_data(self._scene_element,"cubemap_uri",False) + self.properties.shadows=common.get_xml_data(self._scene_element,"shadows",False) + self.properties.grid=common.get_xml_data(self._scene_element,"grid",False) + self.properties.origin_visual=common.get_xml_data(self._scene_element,"origin_visual",False) + self.properties.fog_color=common.get_xml_data(self._scene_element,"color",False) + self.properties.fog_type=common.get_xml_data(self._scene_element,"type",False) + self.properties.fog_start=common.get_xml_data(self._scene_element,"start",False) + self.properties.fog_end=common.get_xml_data(self._scene_element,"end",False) + self.properties.fog_density=common.get_xml_data(self._scene_element,"density",False) #update color of the color picker buttons color_list=[['fog_color',self.ui.fog_color_picker_btn],['clouds_ambient',self.ui.cloud_ambient_color_pkr], @@ -432,26 +432,14 @@ def reset(self,default:bool=True): doc=FreeCAD.ActiveDocument _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag]) + el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag]) if el_dict is not None: el_str=el_dict["elem_str"] self.merge_elements(self._scene_element,ET.fromstring(el_str)) self.update_ui() def merge_elements(self,destination_el, source_el): - # Update attributes of destination_el with source_el - destination_el.attrib.update(source_el.attrib) - if source_el.text: - destination_el.text = source_el.text - # Merge child elements recursively - for child in source_el: - existing_el = destination_el.find(child.tag) - if existing_el is not None: - self.merge_elements(existing_el, child) # Recursively merge the existing element with the new one - else: - # If the element doesn't exist in destination, simply append it - # destination_el.append(child) - pass + common.merge_elements(destination_el,source_el) @property def element(self): diff --git a/robot_descriptor/sdf_elements/spherical_coordinates.py b/robot_descriptor/sdf_elements/spherical_coordinates.py index ae3bec4..d93f166 100644 --- a/robot_descriptor/sdf_elements/spherical_coordinates.py +++ b/robot_descriptor/sdf_elements/spherical_coordinates.py @@ -1,6 +1,6 @@ -from .. import RD_globals +from .. import common import xml.etree.ElementTree as ET -from ..RD_parser import initialize_element_tree +from ..RD_utils import initialize_element_tree import copy import FreeCAD @@ -134,40 +134,40 @@ def on_reset(self): print("spherical resets applied \n") def on_surface_model(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"surface_model",False,self.properties.surface_model) + common.set_xml_data(self._spherical_coord_elem,"surface_model",False,self.properties.surface_model) def on_world_frame(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"world_frame_orientation",False,self.properties.world_frame_orientation) + common.set_xml_data(self._spherical_coord_elem,"world_frame_orientation",False,self.properties.world_frame_orientation) def on_latitude_deg(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"latitude_deg",False,self.properties.latitude_deg) + common.set_xml_data(self._spherical_coord_elem,"latitude_deg",False,self.properties.latitude_deg) def on_longitude(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"longitude_deg",False,self.properties.longitude_deg) + common.set_xml_data(self._spherical_coord_elem,"longitude_deg",False,self.properties.longitude_deg) def on_elevation(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"elevation",False,self.properties.elevation) + common.set_xml_data(self._spherical_coord_elem,"elevation",False,self.properties.elevation) def on_s_a_eq(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False,self.properties.surface_axis_equatorial) + common.set_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False,self.properties.surface_axis_equatorial) def on_s_a_p(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"surface_axis_polar",False,self.properties.surface_axis_polar) + common.set_xml_data(self._spherical_coord_elem,"surface_axis_polar",False,self.properties.surface_axis_polar) def on_heading(self): - RD_globals.set_xml_data(self._spherical_coord_elem,"heading_deg",False,self.properties.heading_deg) + common.set_xml_data(self._spherical_coord_elem,"heading_deg",False,self.properties.heading_deg) #end callbacks def update_ui(self): - self.properties.surface_model=RD_globals.get_xml_data(self._spherical_coord_elem,"surface_model",False) - self.properties.world_frame_orientation=RD_globals.get_xml_data(self._spherical_coord_elem,"world_frame_orientation",False) - self.properties.latitude_deg=float(RD_globals.get_xml_data(self._spherical_coord_elem,"latitude_deg",False)) - self.properties.longitude_deg=float(RD_globals.get_xml_data(self._spherical_coord_elem,"longitude_deg",False)) - self.properties.elevation=float(RD_globals.get_xml_data(self._spherical_coord_elem,"elevation",False)) - self.properties.surface_axis_equatorial=float(RD_globals.get_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False)) - self.properties.surface_axis_polar=float(RD_globals.get_xml_data(self._spherical_coord_elem,"surface_axis_polar",False)) - self.properties.heading_deg=float(RD_globals.get_xml_data(self._spherical_coord_elem,"heading_deg",False)) + self.properties.surface_model=common.get_xml_data(self._spherical_coord_elem,"surface_model",False) + self.properties.world_frame_orientation=common.get_xml_data(self._spherical_coord_elem,"world_frame_orientation",False) + self.properties.latitude_deg=float(common.get_xml_data(self._spherical_coord_elem,"latitude_deg",False)) + self.properties.longitude_deg=float(common.get_xml_data(self._spherical_coord_elem,"longitude_deg",False)) + self.properties.elevation=float(common.get_xml_data(self._spherical_coord_elem,"elevation",False)) + self.properties.surface_axis_equatorial=float(common.get_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False)) + self.properties.surface_axis_polar=float(common.get_xml_data(self._spherical_coord_elem,"surface_axis_polar",False)) + self.properties.heading_deg=float(common.get_xml_data(self._spherical_coord_elem,"heading_deg",False)) def reset(self,default:bool=True): @@ -176,7 +176,7 @@ def reset(self,default:bool=True): else: doc=FreeCAD.ActiveDocument _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag_name]) + el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag_name]) if el_dict is not None: el_str=el_dict['elem_str'] self.merge(el_str) @@ -186,7 +186,7 @@ def reset(self,default:bool=True): self.update_ui() def merge(self, el_str): - RD_globals.merge_elements(self._spherical_coord_elem,ET.fromstring(el_str)) + common.merge_elements(self._spherical_coord_elem,ET.fromstring(el_str)) @property diff --git a/robot_descriptor/sdf_elements/surface.py b/robot_descriptor/sdf_elements/surface.py new file mode 100644 index 0000000..97a4162 --- /dev/null +++ b/robot_descriptor/sdf_elements/surface.py @@ -0,0 +1,799 @@ +from ..RD_utils import initialize_element_tree +from .. import common +from PySide2 import QtGui,QtCore +import copy +import xml.etree.ElementTree as ET + +class surface_properties: + def __init__(self,ui): + self.ui=ui + +#restitution_coefficient + @property + def restitution_coefficient(self): + return self.ui.collision_restitution_coefficient_sp.value() + @restitution_coefficient.setter + def restitution_coefficient(self,value): + self.ui.collision_restitution_coefficient_sp.setValue(value) + +#threshold + @property + def threshold(self): + return self.ui.collision_bounce_threshold_sp.value() + @threshold.setter + def threshold(self,value): + self.ui.collision_bounce_threshold_sp.setValue(value) + +#friction + #torsional + #coefficient + @property + def coefficient(self): + return self.ui.torsional_coeff_sp.value() + @coefficient.setter + def coefficient(self,value): + self.ui.torsional_coeff_sp.setValue(value) + + #use_patch_radius + @property + def use_patch_radius(self): + return str('true') if self.ui.use_patch_radius_cb.isChecked() else str('false') + @use_patch_radius.setter + def use_patch_radius(self,state): + self.ui.use_patch_radius_cb.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.use_patch_radius_cb.seCheckState(QtCore.Qt.Unchecked) + + #patch_radius + @property + def patch_radius(self): + return self.ui.torsional_patch_radius_sp.value() + @patch_radius.setter + def patch_radius(self,value): + self.ui.torsional_patch_radius_sp.setValue(value) + + #surface_radius + @property + def surface_radius(self): + return self.ui.torsional_surface_radius_sp.value() + @surface_radius.setter + def surface_radius(self,value): + self.ui.torsional_surface_radius_sp.setValue(value) + + #slip + @property + def torsional_slip(self): + self.ui.torsional_ode_slip_sp.value() + + @torsional_slip.setter + def torsional_slip(self,value): + self.ui.torsional_ode_slip_sp.setValue(value) + +#ode + #mu + @property + def friction_ode_mu(self): + return self.ui.surface_ode_mu_sp.value() + @friction_ode_mu.setter + def friction_ode_mu(self,value): + self.ui.surface_ode_mu_sp.setValue(value) + + #mu2 + @property + def friction_ode_mu2(self): + return self.ui.surface_ode_mu2_sp.value() + @friction_ode_mu2.setter + def friction_ode_mu2(self,value): + self.ui.surface_ode_mu2_sp.setValue(value) + + #fdir1 + @property + def friction_ode_fdir1(self): + return [self.ui.surface_ode_fdir1_x_sp.value(),self.ui.surface_ode_fdir1_y_sp.value(),self.ui.surface_ode_fdir1_z_sp.value()] + + @friction_ode_fdir1.setter + def friction_ode_fdir1(self,vals): + self.ui.surface_ode_fdir1_x_sp.setValue(vals[0]) + self.ui.surface_ode_fdir1_y_sp.setValue(vals[1]) + self.ui.surface_ode_fdir1_z_sp.setValue(vals[2]) + + #slip1 + @property + def friction_ode_slip1(self): + return self.ui.surface_ode_slip1_sp.value() + @friction_ode_slip1.setter + def friction_ode_slip1(self,value): + self.ui.surface_ode_slip1_sp.setValue(value) + + #slip2 + @property + def friction_ode_slip2(self): + return self.ui.surface_ode_slip2_sp.value() + @friction_ode_slip2.setter + def friction_ode_slip2(self,value): + self.ui.surface_ode_slip2_sp.setValue(value) + + +#bullet + #friction + @property + def friction_bullet_friction(self): + return self.ui.surface_bullet_friction_sp.value() + @friction_bullet_friction.setter + def friction_bullet_friction(self,value): + self.ui.surface_bullet_friction_sp.setValue(value) + + #friction2 + @property + def friction_bullet_friction2(self): + return self.ui.surface_bullet_friction2_sp.value() + @friction_bullet_friction2.setter + def friction_bullet_friction2(self,value): + self.ui.surface_bullet_friction2_sp.setValue(value) + + #rolling_friction + @property + def friction_bullet_rolling_friction(self): + return self.ui.surface_bullet_rolling_friction_sp.value() + @friction_bullet_rolling_friction.setter + def friction_bullet_rolling_friction(self,value): + self.ui.surface_bullet_rolling_friction_sp.setValue(value) + + @property + def friction_bullet_fdir1(self): + return [self.ui.surface_bullet_fdir1_x_sp.value(),self.ui.surface_bullet_fdir1_x_sp.value(),self.ui.surface_bullet_fdir1_x_sp.value()] + + @friction_bullet_fdir1.setter + def friction_bullet_fdir1(self,vals): + self.ui.surface_bullet_fdir1_x_sp.setValue(vals[0]) + self.ui.surface_bullet_fdir1_x_sp.setValue(vals[1]) + self.ui.surface_bullet_fdir1_x_sp.setValue(vals[2]) + + +#contact + @property + def collide_without_contact(self): + return str('true') if self.ui.contact_collide_without_contact_cb.isChecked() else str('false') + @collide_without_contact.setter + def collide_without_contact(self,state): + self.ui.contact_collide_without_contact_cb.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.contact_collide_without_contact_cb.setCheckState(QtCore.Qt.Unchecked) + + #collide_without_contact_bitmask + @property + def collide_without_contact_bitmask(self): + return self.ui.contact_collide_without_contact_bitmask_sp.value() + @collide_without_contact_bitmask.setter + def collide_without_contact_bitmask(self,val): + self.ui.contact_collide_without_contact_bitmask_sp.setValue(val) + + @property + def collide_bitmask(self): + return self.ui.contact_collide_bitmask_sp.value() + @collide_bitmask.setter + def collide_bitmask(self,value): + self.ui.contact_collide_bitmask_sp.setValue(value) + + @property + def category_bitmask(self): + return self.ui.contact_category_bitmask_sp.value() + @category_bitmask.setter + def category_bitmask(self,value): + self.ui.contact_category_bitmask_sp.setValue(value) + + @property + def poissons_ratio(self): + return self.ui.contact_poissons_ratio_sp.value() + @poissons_ratio.setter + def poissons_ratio(self,value): + self.ui.contact_poissons_ratio_sp.setValue(value) + + @property + def elastic_modulus(self): + return self.ui.contact_elastic_modulus_sp.value() + @elastic_modulus.setter + def elastic_modulus(self,value): + self.ui.contact_elastic_modulus_sp.setValue(value) + #ode + + @property + def contact_ode_soft_cfm(self): + return self.ui.contact_ode_soft_cfm_sp.value() + @contact_ode_soft_cfm.setter + def contact_ode_soft_cfm(self,value): + self.ui.contact_ode_soft_cfm_sp.setValue(value) + + @property + def contact_ode_soft_erp(self): + return self.ui.contact_ode_soft_erp_sp.value() + @contact_ode_soft_erp.setter + def contact_ode_soft_erp(self,value): + self.ui.contact_ode_soft_erp_sp.setValue(value) + + @property + def contact_ode_kp(self): + return self.ui.contact_ode_kp_sp.value() + @contact_ode_kp.setter + def contact_ode_kp(self,value): + self.ui.contact_ode_kp_sp.setValue(value) + + @property + def contact_ode_kd(self): + return self.ui.contact_ode_kd_sp.value() + @contact_ode_kd.setter + def contact_ode_kd(self,value): + self.ui.contact_ode_kd_sp.setValue(value) + + @property + def contact_ode_max_vel(self): + return self.ui.contact_ode_max_vel_sp.value() + @contact_ode_max_vel.setter + def contact_ode_max_vel(self,value): + self.ui.contact_ode_max_vel_sp.setValue(value) + + @property + def contact_ode_min_depth(self): + return self.ui.contact_ode_min_depth_sp.value() + @contact_ode_min_depth.setter + def contact_ode_min_depth(self,value): + self.ui.contact_ode_min_depth_sp.setValue(value) + + #bullet + @property + def contact_bullet_soft_cfm(self): + return self.ui.contact_bullet_soft_cfm_sp.value() + @contact_bullet_soft_cfm.setter + def contact_bullet_soft_cfm(self,value): + self.ui.contact_bullet_soft_cfm_sp.setValue(value) + + @property + def contact_bullet_soft_erp(self): + return self.ui.contact_bullet_soft_erp_sp.value() + @contact_bullet_soft_erp.setter + def contact_bullet_soft_erp(self,value): + self.ui.contact_bullet_soft_erp_sp.setValue(value) + + @property + def contact_bullet_kp(self): + return self.ui.contact_bullet_kp_sp.value() + @contact_bullet_kp.setter + def contact_bullet_kp(self,value): + self.ui.contact_bullet_kp_sp.setValue(value) + + @property + def contact_bullet_kd(self): + return self.ui.contact_bullet_kd_sp.value() + @contact_bullet_kd.setter + def contact_bullet_kd(self,value): + self.ui.contact_bullet_kd_sp.setValue(value) + + @property + def contact_bullet_split_impulse(self): + return str('true') if self.ui.contact_bullet_split_impulse_cb.isChecked() else str('false') + @contact_bullet_split_impulse.setter + def contact_bullet_split_impulse(self,state): + self.ui.contact_bullet_split_impulse_cb.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.contact_bullet_split_impulse_cb.setCheckState(QtCore.Qt.Unchecked) + + @property + def split_impulse_penetration_threshold(self): + return self.ui.split_impulse_penetration_threshold_sp.value() + @split_impulse_penetration_threshold.setter + def split_impulse_penetration_threshold(self,value): + self.ui.split_impulse_penetration_threshold_sp.setValue(value) + +#soft contact + @property + def bone_attachment(self): + return self.ui.soft_contact_bone_attachment_sp.value() + @bone_attachment.setter + def bone_attachment(self,value): + self.ui.soft_contact_bone_attachment_sp.setValue(value) + + + @property + def stiffness(self): + return self.ui.soft_contact_stiffness_sp.value() + @stiffness.setter + def stiffness(self,value): + self.ui.soft_contact_stiffness_sp.setValue(value) + + @property + def damping(self): + return self.ui.soft_body_damping_sp.value() + @damping.setter + def damping(self,value): + self.ui.soft_body_damping_sp.setValue(value) + + @property + def flesh_mass_fraction(self): + return self.ui.soft_contact_flesh_mass_fraction_sp.value() + @flesh_mass_fraction.setter + def flesh_mass_fraction(self,value): + self.ui.soft_contact_flesh_mass_fraction_sp.setValue(value) + +#========================================= +#_cb +#============================================ + #control checkboxes +#friction + @property + def surface_ode_mu_cb(self): + return self.ui.surface_ode_mu_cb.isChecked() + + @property + def surface_ode_mu2_cb(self): + return self.ui.surface_ode_mu2_cb.isChecked() + + @property + def surface_ode_slip1_cb(self): + return self.ui.surface_ode_slip1_cb.isChecked() + + @property + def surface_ode_slip2_cb(self): + return self.ui.surface_ode_slip2_cb.isChecked() + + @property + def surface_bullet_friction_cb(self): + return self.ui.surface_bullet_friction_cb.isChecked() + + @property + def surface_bullet_friction2_cb(self): + return self.ui.surface_bullet_friction2_cb.isChecked() + + @property + def surface_bullet_rolling_friction_cb(self): + return self.ui.surface_bullet_rolling_friction_cb.isChecked() + + @property + def ode_frdir1_groupbox(self): + return self.ui.ode_frdir1_groupbox.isChecked() + @property + def bullet_frdir1_groupbox(self): + return self.ui.bullet_frdir1_groupbox.isChecked() + + +#contact + @property + def contact_collide_without_contact_bitmask_cb(self): + return self.ui.contact_collide_without_contact_bitmask_cb.isChecked() + + @property + def contact_collide_bitmask_cb(self): + return self.ui.contact_collide_bitmask_cb.isChecked() + + @property + def contact_category_bitmask_cb(self): + return self.ui.contact_category_bitmask_cb.isChecked() + + @property + def contact_poissons_ratio_cb(self): + return self.ui.contact_poissons_ratio_cb.isChecked() + + @property + def contact_ode_soft_cfm_cb(self): + return self.ui.contact_ode_soft_cfm_cb.isChecked() + + @property + def contact_ode_soft_erp_cb(self): + return self.ui.contact_ode_soft_erp_cb.isChecked() + + @property + def contact_ode_kp_cb(self): + return self.ui.contact_ode_kp_cb.isChecked() + + @property + def contact_ode_kd_cb(self): + return self.ui.contact_ode_kd_cb.isChecked() + + @property + def contact_ode_max_vel_cb(self): + return self.ui.contact_ode_max_vel_cb.isChecked() + + @property + def contact_ode_min_depth_cb(self): + return self.ui.contact_ode_min_depth_cb.isChecked() + + @property + def contact_bullet_soft_cfm_cb(self): + return self.ui.contact_bullet_soft_cfm_cb.isChecked() + + @property + def contact_bullet_soft_erp_cb(self): + return self.ui.contact_bullet_soft_erp_cb.isChecked() + + @property + def contact_bullet_kp_cb(self): + return self.ui.contact_bullet_kp_cb.isChecked() + + @property + def contact_bullet_kd_cb(self): + return self.ui.contact_bullet_kd_cb.isChecked() + + +#======================================= +#=======surface =================== +#================================ + +class surface: + def __init__(self,ui) -> None: + self.ui=ui + self.properties=surface_properties(self.ui) + self.file_name="surface.sdf" + self.tag="surface" + self.surface_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element + self.configUI() + self.updateUI() + + + def configUI(self): + #bounce + # bounce=self.surface_element.find('bounce') + self.ui.collision_restitution_coefficient_sp.valueChanged.connect(lambda val,bounce=self.surface_element.find('bounce'): + common.set_xml_data(bounce,"restitution_coefficient",False,self.properties.restitution_coefficient)) + + self.ui.collision_bounce_threshold_sp.valueChanged.connect(lambda val,bounce=self.surface_element.find('bounce'): + common.set_xml_data(bounce,"threshold",False,self.properties.threshold)) + + #torsional + # torsional=self.surface_element.find(".//friction/torsional") + self.ui.torsional_coeff_sp.valueChanged.connect(lambda val: + common.set_xml_data(self.surface_element.find(".//friction/torsional"),"coefficient",False,self.properties.coefficient)) + self.ui.use_patch_radius_cb.stateChanged.connect(lambda val: + common.set_xml_data(self.surface_element.find(".//friction/torsional"),"use_patch_radius",False,self.properties.use_patch_radius)) + + self.ui.torsional_patch_radius_sp.valueChanged.connect(lambda val: + common.set_xml_data(self.surface_element.find(".//friction/torsional"),"patch_radius",False,self.properties.patch_radius)) + + self.ui.torsional_surface_radius_sp.valueChanged.connect(lambda val: + common.set_xml_data(self.surface_element.find(".//friction/torsional"),"surface_radius",False,self.properties.surface_radius)) + + self.ui.torsional_ode_slip_sp.valueChanged.connect(lambda val: + common.set_xml_data(self.surface_element.find(".//friction/torsional"),"slip",False,self.properties.torsional_slip)) + + #frictional_ode + # frictional_ode=self.surface_element.find(".//friction/ode") + + self.ui.surface_ode_mu_sp.valueChanged.connect(lambda val: + common.set_xml_data(self.surface_element.find(".//friction/ode"),"mu",False,self.properties.friction_ode_mu)) + + self.ui.surface_ode_mu2_sp.valueChanged.connect( + lambda val: + common.set_xml_data(self.surface_element.find(".//friction/ode"),"mu2",False,self.properties.friction_ode_mu2) + ) + + self.ui.surface_ode_slip1_sp.valueChanged.connect( + lambda val: + common.set_xml_data(self.surface_element.find(".//friction/ode"),"slip1",False,self.properties.friction_ode_slip1) + ) + + self.ui.surface_ode_slip2_sp.valueChanged.connect( + lambda val: + common.set_xml_data(self.surface_element.find(".//friction/ode"),"slip2",False,self.properties.friction_ode_slip2) + ) + + self.ui.surface_ode_fdir1_x_sp.valueChanged.connect(self.ode_fdir1) + self.ui.surface_ode_fdir1_y_sp.valueChanged.connect(self.ode_fdir1) + self.ui.surface_ode_fdir1_z_sp.valueChanged.connect(self.ode_fdir1) + + #frictional_bullet + # frictional_bullet=self.surface_element.find(".//fiction/bullet") + self.ui.surface_bullet_friction_sp.valueChanged.connect( + lambda val: + common.set_xml_data(self.surface_element.find(".//friction/bullet"),"friction",False,self.properties.friction_bullet_friction)) + self.ui.surface_bullet_friction2_sp.valueChanged.connect( + lambda val: + common.set_xml_data(self.surface_element.find(".//friction/bullet"),"friction2",False,self.properties.friction_bullet_friction2) + ) + + self.ui.surface_bullet_rolling_friction_sp.valueChanged.connect( + lambda val: + common.set_xml_data(self.surface_element.find(".//friction/bullet"),"rolling_friction",False,self.properties.friction_bullet_rolling_friction) + ) + + + self.ui.surface_bullet_fdir1_x_sp.valueChanged.connect(self.bullet_fdir1) + self.ui.surface_bullet_fdir1_y_sp.valueChanged.connect(self.bullet_fdir1) + self.ui.surface_bullet_fdir1_z_sp.valueChanged.connect(self.bullet_fdir1) + + #contact + # contact=self.surface_element.find(".//contact") + self.ui.contact_collide_without_contact_cb.stateChanged.connect(self.on_contact_collide_without_contact) + + self.ui.contact_collide_without_contact_bitmask_sp.valueChanged.connect(self.on_contact_collide_without_contact_bitmask) + + self.ui.contact_collide_bitmask_sp.valueChanged.connect(self.on_contact_collide_bitmask) + + self.ui.contact_category_bitmask_sp.valueChanged.connect(self.on_contact_category_bitmask) + self.ui.contact_poissons_ratio_sp.valueChanged.connect(self.on_contact_poissons_ratio) + self.ui.contact_elastic_modulus_sp.valueChanged.connect(self.on_contact_elastic_modulus) + + #ode + + self.ui.contact_ode_soft_cfm_sp.valueChanged.connect(self.on_contact_ode_soft_cfm) + self.ui.contact_ode_soft_erp_sp.valueChanged.connect(self.on_contact_ode_soft_erp) + self.ui.contact_ode_kp_sp.valueChanged.connect(self.on_contact_ode_kp) + self.ui.contact_ode_kd_sp.valueChanged.connect(self.on_contact_ode_kd) + self.ui.contact_ode_max_vel_sp.valueChanged.connect(self.on_contact_ode_max_vel) + self.ui.contact_ode_min_depth_sp.valueChanged.connect(self.on_contact_ode_min_depth) + + #bullet + # contact_bullet=self.surface_element.find(".//contact/bullet") + self.ui.contact_bullet_soft_cfm_sp.valueChanged.connect(self.on_contact_bullet_soft_cfm) + self.ui.contact_bullet_soft_erp_sp.valueChanged.connect(self.on_contact_bullet_soft_erp) + self.ui.contact_bullet_kp_sp.valueChanged.connect(self.on_contact_bullet_kp) + self.ui.split_impulse_penetration_threshold_sp.valueChanged.connect(self.on_split_impulse_penetration_threshold) + self.ui.contact_bullet_kd_sp.valueChanged.connect(self.on_contact_bullet_kd) + self.ui.contact_bullet_split_impulse_cb.stateChanged.connect(self.on_contact_bullet_split_impulse) + + #soft contact + # soft_contact=self.surface_element.find(".//surface/soft_contact") + self.ui.soft_contact_bone_attachment_sp.valueChanged.connect(self.on_soft_contact_bone_attachment) + self.ui.soft_contact_stiffness_sp.valueChanged.connect(self.on_soft_contact_stiffness) + self.ui.soft_body_damping_sp.valueChanged.connect(self.on_soft_body_damping) + self.ui.soft_contact_flesh_mass_fraction_sp.valueChanged.connect(self.on_soft_contact_flesh_mass_fraction) + + #contact + #bullet + def on_contact_bullet_soft_cfm(self): + contact_bullet=self.surface_element.find(".//contact/bullet") + common.set_xml_data(contact_bullet,"soft_cfm",False,self.properties.contact_bullet_soft_cfm) + + def on_contact_bullet_soft_erp(self): + contact_bullet=self.surface_element.find(".//contact/bullet") + common.set_xml_data(contact_bullet,"soft_erp",False,self.properties.contact_bullet_soft_erp) + + def on_contact_bullet_kp(self): + contact_bullet=self.surface_element.find(".//contact/bullet") + common.set_xml_data(contact_bullet,"kp",False,self.properties.contact_bullet_kp) + + def on_split_impulse_penetration_threshold(self): + contact_bullet=self.surface_element.find(".//contact/bullet") + common.set_xml_data(contact_bullet,"split_impulse_penetration_threshold",False,self.properties.split_impulse_penetration_threshold) + + def on_contact_bullet_kd(self): + contact_bullet=self.surface_element.find(".//contact/bullet") + common.set_xml_data(contact_bullet,"kd",False,self.properties.contact_bullet_kd) + + def on_contact_bullet_split_impulse(self): + contact_bullet=self.surface_element.find(".//contact/bullet") + common.set_xml_data(contact_bullet,"split_impulse",False,self.properties.contact_bullet_split_impulse) + + #soft contact + def on_soft_contact_bone_attachment(self): + soft_contact=self.surface_element.find(".//soft_contact") + common.set_xml_data(soft_contact,"bone_attachment",False,self.properties.bone_attachment) + + def on_soft_contact_stiffness(self): + soft_contact=self.surface_element.find(".//soft_contact") + common.set_xml_data(soft_contact,"stiffness",False,self.properties.stiffness) + + def on_soft_body_damping(self): + soft_contact=self.surface_element.find(".//soft_contact") + common.set_xml_data(soft_contact,"damping",False,self.properties.damping) + + def on_soft_contact_flesh_mass_fraction(self): + soft_contact=self.surface_element.find(".//soft_contact") + common.set_xml_data(soft_contact,"flesh_mass_fraction",False,self.properties.flesh_mass_fraction) + + #ode + + def on_contact_ode_soft_cfm(self): + contact_ode=self.surface_element.find(".//contact/ode") + common.set_xml_data(contact_ode,"soft_cfm",False,self.properties.contact_ode_soft_cfm) + + def on_contact_ode_soft_erp(self): + contact_ode=self.surface_element.find(".//contact/ode") + common.set_xml_data(contact_ode,"soft_erp",False,self.properties.contact_ode_soft_erp) + + def on_contact_ode_kp(self): + contact_ode=self.surface_element.find(".//contact/ode") + common.set_xml_data(contact_ode,"kp",False,self.properties.contact_ode_kp) + + def on_contact_ode_kd(self): + contact_ode=self.surface_element.find(".//contact/ode") + common.set_xml_data(contact_ode,"kd",False,self.properties.contact_ode_kd) + + def on_contact_ode_max_vel(self): + contact_ode=self.surface_element.find(".//contact/ode") + common.set_xml_data(contact_ode,"max_vel",False,self.properties.contact_ode_max_vel) + + def on_contact_ode_min_depth(self): + contact_ode=self.surface_element.find(".//contact/ode") + common.set_xml_data(contact_ode,"min_depth",False,self.properties.contact_ode_min_depth) + + #friction + #ode + def ode_fdir1(self): + frictional_ode=self.surface_element.find(".//friction/ode") + common.set_xml_data(frictional_ode,"fdir1",False,self.properties.friction_ode_fdir1) + #bullet + + def bullet_fdir1(self): + frictional_bullet=self.surface_element.find(".//friction/bullet") + common.set_xml_data(frictional_bullet,"fdir1",False,self.properties.friction_bullet_fdir1) + + #contact + def on_contact_collide_without_contact(self): + contact=self.surface_element.find(".//contact") + common.set_xml_data(contact,"collide_without_contact",False,self.properties.collide_without_contact) + + def on_contact_collide_without_contact_bitmask(self): + contact=self.surface_element.find(".//contact") + common.set_xml_data(contact,"collide_without_contact_bitmask",False,self.properties.collide_without_contact_bitmask) + + def on_contact_collide_bitmask(self): + + contact=self.surface_element.find(".//contact") + common.set_xml_data(contact,"collide_bitmask",False,self.properties.collide_bitmask) + + def on_contact_category_bitmask(self): + contact=self.surface_element.find(".//contact") + common.set_xml_data(contact,"category_bitmask",False,self.properties.category_bitmask) + def on_contact_poissons_ratio(self): + contact=self.surface_element.find(".//contact") + common.set_xml_data(contact,"poissons_ratio",False,self.properties.poissons_ratio) + + def on_contact_elastic_modulus(self): + contact=self.surface_element.find(".//contact") + common.set_xml_data(contact,"elastic_modulus",False,self.properties.elastic_modulus) + + + def updateUI(self): + #bounce + bounce=self.surface_element.find('bounce') + #{tag : property} + bounce_pairs={"restitution_coefficient":"restitution_coefficient", + "threshold":"threshold"} + for tag in bounce_pairs.keys(): + setattr(self.properties,bounce_pairs[tag],common.get_xml_data(bounce,tag,False)) + + #torsional + torsional=self.surface_element.find(".//friction/torsional") + #{tag property} + torsional_pairs={"coefficient":"coefficient","use_patch_radius":"use_patch_radius", + "patch_radius":"patch_radius","surface_radius":"surface_radius","slip":"torsional_slip"} + for tag in torsional_pairs.keys(): + setattr(self.properties,torsional_pairs[tag],common.get_xml_data(torsional,tag,False)) + + #friction + #ode + frictional_ode=self.surface_element.find(".//friction/ode") + friction_ode_pairs={"mu":"friction_ode_mu","mu2":"friction_ode_mu2","slip1":"friction_ode_slip1", + "slip2":"friction_ode_slip2","fdir1":"friction_ode_fdir1"} + for tag in friction_ode_pairs.keys(): + setattr(self.properties,friction_ode_pairs[tag],common.get_xml_data(frictional_ode,tag,False)) + + #bullet + frictional_bullet=self.surface_element.find(".//friction/bullet") + friction_bullet_pairs={"friction":"friction_bullet_friction","friction2":"friction_bullet_friction2", + "rolling_friction":"friction_bullet_rolling_friction","fdir1":"friction_bullet_fdir1"} + for tag in friction_bullet_pairs.keys(): + setattr(self.properties,friction_bullet_pairs[tag],common.get_xml_data(frictional_bullet,tag,False)) + + #contact + #contact + contact=self.surface_element.find(".//contact") + contact_pairs={"collide_without_contact":"collide_without_contact","collide_without_contact_bitmask":"collide_without_contact_bitmask", + "category_bitmask":"category_bitmask","poissons_ratio":"poissons_ratio","collide_bitmask":"collide_bitmask", + "elastic_modulus":"elastic_modulus"} + for tag in contact_pairs.keys(): + setattr(self.properties,contact_pairs[tag],common.get_xml_data(contact,tag,False)) + + + #ode + contact_ode=self.surface_element.find(".//contact/ode") + contact_ode_pairs={"soft_cfm":"contact_ode_soft_cfm","soft_erp":"contact_ode_soft_erp", + "kp":"contact_ode_kp","kd":"contact_ode_kd","max_vel":"contact_ode_max_vel", + "min_depth":"contact_ode_min_depth"} + for tag in contact_ode_pairs.keys(): + setattr(self.properties,contact_ode_pairs[tag],common.get_xml_data(contact_ode,tag,False)) + + #bullet + contact_bullet=self.surface_element.find(".//contact/bullet") + contact_bullet_pairs={"soft_cfm":"contact_bullet_soft_cfm","soft_erp":"contact_bullet_soft_erp", + "kp":"contact_bullet_kp","kd":"contact_bullet_kd","split_impulse":"contact_bullet_split_impulse", + "split_impulse_penetration_threshold":"split_impulse_penetration_threshold"} + for tag in contact_bullet_pairs.keys(): + setattr(self.properties,contact_bullet_pairs[tag],common.get_xml_data(contact_bullet,tag,False)) + + #soft contact + soft_contact=self.surface_element.find(".//soft_contact") + #since properties have the same name as the pairs no need for pairs + soft_contact_tags=["bone_attachment","stiffness","damping","flesh_mass_fraction"] + for tag in soft_contact_tags: + setattr(self.properties,tag,common.get_xml_data(soft_contact,tag,False)) + + def reset(self): + pass + + def update_element(self,item): + self.surface_element=item.surface_element + self.updateUI() + + #return element + @property + def element(self): + t_surface_elem=copy.deepcopy(self.surface_element) + #modify bounce + if not self.ui.collision_bounce_groupbox.isChecked(): + t_surface_elem.remove(t_surface_elem.find("bounce")) + + #friction + friction=t_surface_elem.find(".//friction") + if self.ui.surface_friction_groupBox.isChecked(): + #tor countrysion + torsion=friction.find("torsional") + if self.ui.friction_torsional_groupBox.isChecked(): + if not self.ui.torsional_ode_groupbox.isChecked(): + torsion.remove(torsion.find("ode")) + else: + friction.remove(friction.find(torsion)) + #end torsion + + #ode + friction_ode=friction.find("ode") + if self.ui.friction_ode_groupbox.isChecked(): + + elems_attrb_pair={"mu":"surface_ode_mu_cb","mu2":"surface_ode_mu2_cb","slip1":"surface_ode_slip1_cb","slip2":"surface_ode_slip2_cb" + ,"fdir1":"ode_frdir1_groupbox"} + for tag in elems_attrb_pair.keys(): + #remove element if its not enabled + if not getattr(self.properties,elems_attrb_pair[tag]): + friction_ode.remove(friction_ode.find(tag)) + else: + friction.remove(friction.find(friction_ode)) + #end ode + + #bullet + friction_bullet=friction.find("bullet") + if self.ui.surface_friction_bullet_groupbox.ischecked(): + bullet_pairs={"friction":"surface_bullet_friction_cb","friction2":"surface_bullet_friction2_cb","rolling_friction":"surface_bullet_rolling_friction_cb" + ,"fdir1":"bullet_frdir1_groupbox"} + for tag in bullet_pairs.keys(): + if not getattr(self.properties,bullet_pairs[tag]): + friction_bullet.remove(friction_bullet.find(tag)) + else: + friction.remove(friction_bullet) + #end bullet + else: + #remove friction if its not enabled + t_surface_elem.remove(t_surface_elem.find(friction)) + + #end friction + + #contact + contact=t_surface_elem.find("contact") + if self.ui.surface_contact_groupbox.isChecked(): + contact_pairs={"collide_without_contact_bitmask":"contact_collide_without_contact_bitmask_cb","collide_bitmask":"contact_collide_bitmask_cb", + "category_bitmask":"contact_category_bitmask_cb","poissons_ratio":"contact_poissons_ratio_cb","elastic_modulus":"contact_elastic_modulus_cb"} + for tag in contact_pairs.keys(): + if not getattr(self.properties,contact_pairs[tag]): + contact.remove(contact.find(tag)) + #ode + contact_ode=contact.find("ode") + if self.ui.contact_ode_groupbox.isChecked(): + ode_pairs={"soft_cfm":"contact_ode_soft_cfm_cb","soft_erp":"contact_ode_soft_erp_cb","kp":"contact_ode_kp_cb","kd":"contact_ode_kd_cb", + "max_vel":"contact_ode_max_vel_cb","min_depth":"contact_ode_min_depth_cb"} + for tag in ode_pairs.keys(): + if not getattr(self.properties,ode_pairs[tag]): + contact_ode.remove(contact_ode.find(tag)) + else: + contact.remove(contact.find(contact_ode)) + #end ode + + #bullet + contact_bullet=contact.find("bullet") + if self.ui.contact_bullet_groupbox.isChecked(): + bullet_pairs={"soft_cfm":"contact_bullet_soft_cfm_cb","soft_erp":"contact_bullet_soft_erp_cb","kp":"contact_bullet_kp_cb","kd":"contact_bullet_kd_cb"} + for tag in bullet_pairs.keys(): + if not getattr(self.properties,bullet_pairs[tag]): + contact_bullet.remove(tag) + else: + contact.remove(contact.find(contact_bullet)) + #end bullet + else: + t_surface_elem.remove(t_surface_elem.find(contact)) + #end contact + + #soft contact + if not self.ui.soft_contact_dart_groupbox.isChecked(): + t_surface_elem.remove(t_surface_elem.find("soft_contact")) + + return t_surface_elem \ No newline at end of file diff --git a/robot_descriptor/sdf_elements/visual.py b/robot_descriptor/sdf_elements/visual.py new file mode 100644 index 0000000..16ef662 --- /dev/null +++ b/robot_descriptor/sdf_elements/visual.py @@ -0,0 +1,125 @@ +from .. import common +import copy +import FreeCAD,FreeCADGui +from PySide2 import QtCore +from ..RD_utils import initialize_element_tree +import xml.etree.ElementTree as ET +import os + +from . import material + +class visual_properties: + def __init__(self,ui): + self.ui=ui +#shadows + @property + def cast_shadows(self): + return str('true') if self.ui.visual_cast_shadows_checkBox.isChecked() else str('false') + @cast_shadows.setter + def cast_shadows(self,state): + self.ui.visual_cast_shadows_checkBox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.visual_cast_shadows_checkBox.setCheckState(QtCore.Qt.Unchecked) + +#transparency + @property + def transparency(self): + return self.ui.visual_transparency_sp.value() + @transparency.setter + def transparency(self,val): + self.ui.visual_transparency_sp.setValue(val) +#laser retro + @property + def laser_retro(self): + return self.ui.visual_laser_retro_sp.value() + @laser_retro.setter + def laser_retro(self,value): + self.ui.visual_laser_retro_sp.setValue(value) + +#visibility flags + @property + def visibility_flags(self): + return self.ui.visual_visibility_flags_sp.value() + @visibility_flags.setter + def visibility_flags(self,value): + print(value) + self.ui.visual_visibility_flags_sp.setValue(value) + +#check boxes + @property + def visual_laser_retro_cb(self): + return self.ui.visual_laser_retro_cb.isChecked() + + @property + def visual_transparency_cb(self): + return self.ui.visual_transparency_cb.isChecked() + + @property + def visual_visibility_flags_cb(self): + return self.ui.visual_visibility_flags_cb.isChecked() + + +#============= +#==================== +class visual: + def __init__(self,parent_ui): + self.ui=parent_ui + self.file_name="visual.sdf" + self._visual_elem=initialize_element_tree.convdict_2_tree(self.file_name).get_element + self.properties=visual_properties(self.ui) + #maertial + self._material_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,"material.ui")) + self._material_cls=material.material(self._material_ui) + #add widget to parent widget + self.ui.material_scroll.setWidget(self._material_ui.widget) + self.configUI() + self.updateUI() + + + + def configUI(self): + self.ui.visual_laser_retro_sp.valueChanged.connect(self.on_laser_retro) + self.ui.visual_transparency_sp.valueChanged.connect(self.on_transparency) + self.ui.visual_visibility_flags_sp.valueChanged.connect(self.on_visibility_flags) + self.ui.visual_cast_shadows_checkBox.stateChanged.connect(self.on_cast_shadows) + + def on_laser_retro(self): + element=self._visual_elem + common.set_xml_data(element,"laser_retro",False,self.properties.laser_retro) + + def on_transparency(self): + element=self._visual_elem + common.set_xml_data(element,"transparency",False,self.properties.transparency) + + def on_visibility_flags(self): + element=self._visual_elem + common.set_xml_data(element,"visibility_flags",False,self.properties.visibility_flags) + + def on_cast_shadows(self): + element=self._visual_elem + common.set_xml_data(element,"cast_shadows",False,self.properties.cast_shadows) + + + def updateUI(self): + self.properties.laser_retro=common.get_xml_data(self._visual_elem,"laser_retro",False) + self.properties.transparency=common.get_xml_data(self._visual_elem,"transparency",False) + #this causes an overflow so dont update for now , ui is also disabled , + # t + # self.properties.visibility_flags=common.get_xml_data(self._visual_elem,"visibility_flags",False) + self.properties.cast_shadows=common.get_xml_data(self._visual_elem,"cast_shadows",False) + + def update_elements(self,item): + self._visual_elem=item._visual_element + self._material_cls.update_elements(item) + self.updateUI() + + @property + def element(self): + t_visual_elem=copy.deepcopy(self._visual_elem) + visual_pairs={"laser_retro":"visual_laser_retro_cb","transparency":"visual_transparency_cb","visibility_flags":"visual_visibility_flags_cb"} + for tag in visual_pairs.keys(): + if not getattr(self.properties,visual_pairs[tag]): + t_visual_elem.remove(t_visual_elem.find(tag)) + if t_visual_elem.find("material") is None: + t_visual_elem.append(self._material_cls.element) + return t_visual_elem + + \ No newline at end of file diff --git a/robot_descriptor/sdf_elements/world.py b/robot_descriptor/sdf_elements/world.py index 2cfa462..f825281 100644 --- a/robot_descriptor/sdf_elements/world.py +++ b/robot_descriptor/sdf_elements/world.py @@ -5,11 +5,11 @@ import copy import xml.etree.ElementTree as ET -from .. import RD_globals +from .. import common #reponsible for creating an element tree using xml.etree -from ..RD_parser import initialize_element_tree +from ..RD_utils import initialize_element_tree -_icon_dir__=os.path.join(RD_globals.ICON_PATH,"world_properties.svg") +_icon_dir__=os.path.join(common.ICON_PATH,"world_properties.svg") '''setters will do nothing for optional part ''' @@ -104,13 +104,13 @@ def wind(self,wind_vec:list)->bool: #------------------------------------------------------ class world(): def __init__(self): - super(world,self).__init__() + self.parent_path=["sdf"] self.tag='world' self.file_name="world.sdf" - - self.ui_path=os.path.join(RD_globals.UI_PATH,"world.ui") + self.ui_path=os.path.join(common.UI_PATH,"world.ui") self.world_form=FreeCADGui.PySideUic.loadUi(self.ui_path) + #get main window for use in aligning mw=FreeCADGui.getMainWindow() #centre dialog to main window self.world_form.move( @@ -142,19 +142,21 @@ def __init__(self): self.configUI() #update ui with previously configured values if available + self.reset(False) - + #display window + self.world_form.exec_() #window close event this is called when the (x) widget icon is pressed def closeEvent(self, event): print('closing widget\n') event.accept() def update_ui(self): - self.properties.name=RD_globals.get_xml_data(self.world_elem,["world","name"],True) - self.properties.gravity=RD_globals.get_xml_data(self.world_elem,"gravity",False) - self.properties.wind=RD_globals.get_xml_data(self.world_elem,"linear_velocity",False) - self.properties.audio=RD_globals.get_xml_data(self.world_elem,"device",False) - self.properties.magnetic_field=RD_globals.get_xml_data(self.world_elem,"magnetic_field",False) + self.properties.name=common.get_xml_data(self.world_elem,["world","name"],True) + self.properties.gravity=common.get_xml_data(self.world_elem,"gravity",False) + self.properties.wind=common.get_xml_data(self.world_elem,"linear_velocity",False) + self.properties.audio=common.get_xml_data(self.world_elem,"device",False) + self.properties.magnetic_field=common.get_xml_data(self.world_elem,"magnetic_field",False) #this will be called by the reset callback def reset(self,default:bool=True): @@ -166,7 +168,7 @@ def reset(self,default:bool=True): else: doc=FreeCAD.ActiveDocument _root_dict=doc.Robot_Description.Proxy.element_dict - el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag]) + el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag]) if el_dict is not None: el_str=el_dict['elem_str'] self.merge(el_str) @@ -177,7 +179,7 @@ def reset(self,default:bool=True): self.update_ui() def merge(self, el_str): - RD_globals.merge_elements(self.world_elem,ET.fromstring(el_str)) + common.merge_elements(self.world_elem,ET.fromstring(el_str)) def configUI(self): self.world_form.world_name_input.textEdited.connect(self.on_world_name) @@ -204,8 +206,7 @@ def configUI(self): # reset Pb self.world_form.world_reset_btn.clicked.connect(self.on_reset) - #display window - self.world_form.exec_() + def update_element(self): @@ -230,15 +231,15 @@ def on_reset(self): def on_world_name(self): name=self.properties.name - RD_globals.set_xml_data(self.world_elem,"world",True,{"name":name}) + common.set_xml_data(self.world_elem,"world",True,{"name":name}) def on_gravity(self): - RD_globals.set_xml_data(self.world_elem,"gravity",False,self.properties.gravity) + common.set_xml_data(self.world_elem,"gravity",False,self.properties.gravity) def on_magn(self): - RD_globals.set_xml_data(self.world_elem,"magnetic_field",False,self.properties.magnetic_field) + common.set_xml_data(self.world_elem,"magnetic_field",False,self.properties.magnetic_field) def on_wind(self): - RD_globals.set_xml_data(self.world_elem,"linear_velocity",False,self.properties.wind) + common.set_xml_data(self.world_elem,"linear_velocity",False,self.properties.wind) def on_audio(self): - RD_globals.set_xml_data(self.world_elem,"device",False,self.properties.audio) + common.set_xml_data(self.world_elem,"device",False,self.properties.audio) #ok push button pressed callback def on_ok(self): @@ -248,33 +249,33 @@ def on_ok(self): def on_apply_pb(self): #read string element data from RD_description proxy updated_elem=self.update_element() - RD_globals.update_dictionary(self.parent_path,self.tag,updated_elem) + common.update_dictionary(self.parent_path,self.tag,updated_elem) #append elements in hierachy as they are supposed to appear in the tree e.g world is appended #before atmosphere since its atmospheres parent, this helpsFreeCADGui.PySideUic.loadUi(self.ui_path,self) reduce the complexity #of having to implement a way of ensuring parents are available # dont add atmosphere element if the group box is not checked if self.atmosphere.is_checked(): - RD_globals.update_dictionary(self.atmosphere.parent_path,self.atmosphere.tag,self.atmosphere.atmosphere_element) + common.update_dictionary(self.atmosphere.parent_path,self.atmosphere.tag,self.atmosphere.atmosphere_element) #add physics properties - RD_globals.update_dictionary(self._physics.parent_path,self._physics.tag,self._physics.element) + common.update_dictionary(self._physics.parent_path,self._physics.tag,self._physics.element) #add spherical coordiates if self.world_form.spherical_coordinates_groupbox.isChecked(): - RD_globals.update_dictionary( + common.update_dictionary( self._spherical_coordinates.parent_path, self._spherical_coordinates.tag_name, self._spherical_coordinates.spherical_cood_elem) #dont attempt to add a lights if there are no light sources if len(self._lights.lights) >0: - RD_globals.update_dictionary(self._lights.parent_path,self._lights.tag,self._lights.element) + common.update_dictionary(self._lights.parent_path,self._lights.tag,self._lights.element) #add scene based on state of a checkbox if self.world_form.enable_scene_checkBox.isChecked(): - RD_globals.update_dictionary(self._scene.parent_path,self._scene.tag,self._scene.element) + common.update_dictionary(self._scene.parent_path,self._scene.tag,self._scene.element) #append the road element - if self.world_form.enable_road_checkbox.isChecked(): - RD_globals.update_dictionary(self._road.parent_path,self._road.tag,self._road.element) + if self.world_form.include_material_info.isChecked(): + common.update_dictionary(self._road.parent_path,self._road.tag,self._road.element) print("updated\n")