def openTask(self, container=None): self.doc = App.ActiveDocument if container is None else container.Document self.doc.openTransaction("Placement Shooter") self.container = container if self.container is None: self.container = makeJoinArrays('ShotArray') self.updateMessage() self.visibilityAutomationBegin() Gui.Control.closeDialog() #just in case something else was being shown Gui.Control.showDialog(self) Gui.Selection.clearSelection() Gui.Selection.addObserver(self)
custom_pls = [] for ifc_mapped_item in ifc_shape_representation.Items: ifc_cartesian_point = ifc_mapped_item.MappingTarget.LocalOrigin coord = ifc_cartesian_point.Coordinates custom_pl = lattice2Placement.makeLatticePlacement( name=str(ifc_cartesian_point.id())) custom_pl.PlacementChoice = "Custom" custom_pl.MarkerSize = 25 lattice2Executer.executeFeature(custom_pl) custom_pl.Placement = FreeCAD.Placement( vec(coord[0], coord[1], coord[2]), FreeCAD.Rotation(vec(0, 0, 1), 0), vec(0, 0, 0)) custom_pls.append(custom_pl) # lattice2 array placement cpa = lattice2JoinArrays.makeJoinArrays(name="CustomPlacementArray") cpa.Links = custom_pls cpa.MarkerSize = 25 for child in cpa.ViewObject.Proxy.claimChildren(): child.ViewObject.hide() lattice2Executer.executeFeature(cpa) ifc_cartesian_point_cpa = rebar.ObjectPlacement.RelativePlacement.Location coord_cpa = ifc_cartesian_point_cpa.Coordinates cpa_pl = FreeCAD.Placement(vec(coord_cpa[0], coord_cpa[1], coord_cpa[2]), FreeCAD.Rotation(vec(0, 0, 1), 0), vec(0, 0, 0)) cpa.Placement = cpa_pl # move rebar shape to the first bar of distribution rebar_shape.Placement = cpa_pl
def insert(filename, docname, skip=[], only=[], root=None): """insert(filename,docname,skip=[],only=[],root=None): imports the contents of an IFC file. skip can contain a list of ids of objects to be skipped, only can restrict the import to certain object ids (will also get their children) and root can be used to import only the derivates of a certain element type (default = ifcProduct).""" getPreferences() # ***************************************************************** # we are going to overwrite skip and only # needs to be after getPreferences # skip = [1030, 1922, 9813, 13030, 28999, 30631, 34909, 39120] # # only = [679567] # add this modules to the modules to reload on my reload tool try: import ifcopenshell except: FreeCAD.Console.PrintError( "IfcOpenShell was not found on this system. " "IFC support is disabled\n") return if DEBUG: print("Opening ", filename, "...", end="") try: doc = FreeCAD.getDocument(docname) except: doc = FreeCAD.newDocument(docname) FreeCAD.ActiveDocument = doc if DEBUG: print("done.") global ROOT_ELEMENT if root: ROOT_ELEMENT = root from ifcopenshell import geom settings = ifcopenshell.geom.settings() settings.set(settings.USE_BREP_DATA, True) settings.set(settings.SEW_SHELLS, True) settings.set(settings.USE_WORLD_COORDS, True) settings.set(settings.DISABLE_OPENING_SUBTRACTIONS, False) settings.set(settings.INCLUDE_CURVES, True) settings.set(settings.EXCLUDE_SOLIDS_AND_SURFACES, True) # global ifcfile # keeping global for debugging purposes filename = ifcdecode(filename, utf=True) ifcfile = ifcopenshell.open(filename) # get the length scale facter from of unit of the ifc file length_scale = get_prj_unit_length_scale(ifcfile) print("Length scale = {}\n".format(length_scale)) reinforcements = ifcfile.by_type("IfcReinforcingBar") rebar_objs = [] base_rebars = {} # {rebar_mark_number : rebar_obj} reinforcement_counter = 1 # reinforcements for pno, rebar in enumerate(reinforcements): pid = rebar.id() ptype = rebar.is_a() print("Product {} of {} is Entity #{}: {}, ".format( pno + 1, len(reinforcements), pid, ptype, ), end="", flush=True) if pid in skip: print(" --> is in skip list, thus skipped", end="\n") continue if only and pid not in only: print( " --> only list is no empty and pid " "not in only list, thus skipped", end="\n") continue # properties, get the mark number # print("") # build list of related property sets psets = getIfcPropertySets(ifcfile, pid) # print(psets) # build dict of properties ifc_properties = {} rebar_mark_number = 0 ifc_properties = getIfcProperties(ifcfile, pid, psets, ifc_properties) # print(ifc_properties) # get the mark number (Position number) for key, value in ifc_properties.items(): pset, pname, ptype, pvalue = getPropertyData( key, value, {"Debug": True}) if (pset == "Allplan_ReinforcingBar" and pname == "Position number" # need to be Position not Mark! ): rebar_mark_number = pvalue # print(rebar_mark_number) # print("") # for debugging, TODO some Parameter to only import certain mark numbers # if rebar_mark_number != 3: # continue # get the radius and the IfcCurve (Directrix) out of the ifc ifc_shape_representation = rebar.Representation.Representations[0] item_ifc_shape_representation = ifc_shape_representation.Items[0] mapping_source = item_ifc_shape_representation.MappingSource ifc_swept_disk_solid = mapping_source.MappedRepresentation.Items[0] radius = ifc_swept_disk_solid.Radius * length_scale # print(radius) entity_polyline = ifc_swept_disk_solid.Directrix # sweep path # get the geometry out of the IfcCurve (Directrix) and create a Wire cr = ifcopenshell.geom.create_shape(settings, entity_polyline) brep = cr.brep_data sweep_path = Part.Shape() sweep_path.importBrepFromString(brep) sweep_path.scale(1000.0) # IfcOpenShell always outputs in meters # does it makes sense to check if the sweep_path and Radius # really are the same if mark number equals (yes, thus TODO) base_placement = FreeCAD.Placement() if rebar_mark_number not in base_rebars: # create a new rebar shape wire = Draft.makeWire(sweep_path.Wires[0]) rebar_shape = archadd.BaseRebar(wire, diameter=2 * radius, mark=rebar_mark_number, name="BaseRebar_Mark_" + str(rebar_mark_number)) rebar_shape.IfcProperties = ifc_properties print("based on: {}, ".format(wire.Name), end="") rebar_objs.append(rebar_shape) base_rebars[rebar_mark_number] = rebar_shape else: # get the relative placement between # the base wire (the one in base_rebars already) # the sweep_path base_wire_obj = base_rebars[rebar_mark_number].Base print("based on: {}, ".format(base_wire_obj.Name), end="") base_placement = get_relative_placement(base_wire_obj.Shape, sweep_path) # print(base_placement) # reinforcement made out of the imported rebar # coord placements vec_base_rebar = [] for ifc_mapped_item in ifc_shape_representation.Items: ifc_cartesian_point = ifc_mapped_item.MappingTarget.LocalOrigin coord = ifc_cartesian_point.Coordinates co_vec = vec(coord[0] * length_scale, coord[1] * length_scale, coord[2] * length_scale) vec_base_rebar.append(co_vec) # print("\n{}".format(vec_base_rebar)) # check if we have a linear reinforcement is_linear_reinforcement = False space_one = 0 if len(vec_base_rebar) > 1: # edge from first point to last point ed = Part.Edge( Part.LineSegment(vec_base_rebar[0], vec_base_rebar[-1])) # spacing between first and second point space_one = vec_base_rebar[1] - vec_base_rebar[0] for i, co_vec in enumerate(vec_base_rebar): # check distance point to edge dist = ed.distToShape(Part.Vertex(co_vec))[0] if dist > 2: # 2 mm, much better would be some dimensionless value break # check spaceing, if they are constant if i > 0: space_i = vec_base_rebar[i] - vec_base_rebar[i - 1] difference_length = (space_one - space_i).Length if difference_length > 2: # 2 mm, much better would be some dimensionless value break else: is_linear_reinforcement = True # get placement for first reinforcement bar relplacement_firstbar = rebar.ObjectPlacement.RelativePlacement coord_firstbar = relplacement_firstbar.Location.Coordinates vec_firstbar = vec(coord_firstbar[0] * length_scale, coord_firstbar[1] * length_scale, coord_firstbar[2] * length_scale) firstbar_pl = FreeCAD.Placement(vec_firstbar, FreeCAD.Rotation(vec(0, 0, 1), 0), vec(0, 0, 0)) marker_size = 25 lattice_placement = None if (REINFORCEMENT_LATTICE is True and is_linear_reinforcement is True): # linear lattice reinforcement print("reinforcement: linear lattice") # print(len(vec_base_rebar)) # print(space_one) space_length = space_one.Length la = lattice2LinearArray.makeLinearArray(name="LinearArray") # SpanN ... put in Count # Step will be calculated # SpanStep ... put in Step (space between rebars) # Count will be calculated la.GeneratorMode = "SpanStep" # https://forum.freecadweb.org/viewtopic.php?f=22&t=37657#p320586 la.Alignment = "Justify" la.SpanEnd = (len(vec_base_rebar) - 1) * space_length la.Step = space_length la.MarkerSize = marker_size # direction of linear lattice2 placement la.Dir = space_one # do not change the orientation of the little planes # https://forum.freecadweb.org/viewtopic.php?f=22&t=37893&p=322427#p322421 la.OrientMode = "None" lattice2Executer.executeFeature(la) la.Placement = firstbar_pl if la.Count != len(vec_base_rebar): print("Problem: {} != {}".format(la.Count, len(vec_base_rebar))) lattice_placement = la elif (REINFORCEMENT_LATTICE is True and is_linear_reinforcement is False): # custom lattice placement for every rebar of this reinforcement print("reinforcement: custom lattice") custom_pls = [] for co_vec in vec_base_rebar: custom_pl = lattice2Placement.makeLatticePlacement( name=str(ifc_cartesian_point.id())) custom_pl.PlacementChoice = "Custom" custom_pl.MarkerSize = marker_size lattice2Executer.executeFeature(custom_pl) custom_pl.Placement = FreeCAD.Placement( co_vec, FreeCAD.Rotation(vec(0, 0, 1), 0), vec(0, 0, 0)) custom_pls.append(custom_pl) # lattice array placement from custom lattice placements cpa = lattice2JoinArrays.makeJoinArrays( name="CustomPlacementArray") cpa.Links = custom_pls cpa.MarkerSize = marker_size lattice2Executer.executeFeature(cpa) cpa.Placement = firstbar_pl lattice_placement = cpa if FreeCAD.GuiUp: for child in cpa.ViewObject.Proxy.claimChildren(): child.ViewObject.hide() if lattice_placement is not None: # lattice2 reinforcement archadd.ReinforcementLattice( rebar_shape, lattice_placement, base_placement, # name="Reinforcement_"+str(reinforcement_counter) name="ReinforcementLattice_" + str(pid)) if (REINFORCEMENT_LATTICE is False and is_linear_reinforcement is True): # linear reinforcement print("reinforcement: linear std") if space_one == 0: # TODO handle a reinforcement with one rebar # this should not be a linear reinforcement continue amount = len(vec_base_rebar) spacing = space_one.Length # distance = (len(vec_base_rebar) - 1) * spacing archadd.ReinforcementLinear( rebar_shape, amount=amount, spacing=spacing, direction=space_one, base_placement=firstbar_pl.multiply(base_placement), # name="Reinforcement_"+str(reinforcement_counter) name="ReinforcementLinear_" + str(pid)) elif (REINFORCEMENT_LATTICE is False and is_linear_reinforcement is False): # individual reinforcement print("reinforcement: individual std") individuals = [] for co in vec_base_rebar: v_placement_lok = FreeCAD.Placement(co, FreeCAD.Rotation()) v_placement_glob = v_placement_lok.multiply(firstbar_pl) v = doc.addObject("Part::Vertex", "Vertex1") v_vec = v_placement_glob.Base v.X, v.Y, v.Z = v_vec.x, v_vec.y, v_vec.z, v.ViewObject.PointColor = (1.0, 0.7, 0.0, 0.0) v.ViewObject.PointSize = 15 individuals.append(v) archadd.ReinforcementIndividual(rebar_shape, individuals=individuals, base_placement=base_placement, name="ReinforcementIndividual_" + str(pid)) reinforcement_counter += 1 # print("") FreeCAD.ActiveDocument.recompute() # End reinforcements loop if FreeCAD.GuiUp: FreeCADGui.activeDocument().activeView().viewAxometric() FreeCADGui.SendMsgToActiveView("ViewFit") return doc