예제 #1
0
def addObjectsByDuplication(N=1,
                            createObjectFunction=bpy.ops.object.empty_add,
                            GUI_loaded=False):
    '''
  Until we figure out a way to allocate space for objects to add them faster, we work around the problem by using blender's duplicate function.
  This means the number of objects increases according to a 2^n series.
  
  .. note:: This function is currently unused...
  '''
    ## progress indicator does not work when running from CLI
    if GUI_loaded:
        bpy.context.window_manager.progress_begin(0, 100)

    # we will store added objects in a list
    L = N * [0]
    current_idx = 0

    # deselect all
    bpy.ops.object.select_all(action='DESELECT')

    # add first object
    createObjectFunction()
    L[current_idx] = bpy.context.object
    current_idx += 1

    # duplicate
    while 2 * current_idx <= N:
        sub_start_time = time.time()

        bpy.ops.object.select_linked()

        print(('current_idx =', current_idx, 'selection =',
               len(bpy.context.selected_objects)))

        bpy.ops.object.duplicate_move_linked()

        L[current_idx:current_idx +
          len(bpy.context.selected_objects)] = bpy.context.selected_objects
        current_idx += len(bpy.context.selected_objects)
        if GUI_loaded:
            bpy.context.window_manager.progress_update(current_idx / N)
        else:
            print(('progress =', current_idx / N))
        print('Elapsed time: ', round(time.time() - sub_start_time, 4),
              'seconds')

    print('Last duplication...')
    selectObjects(L[0:N - current_idx])
    bpy.ops.object.duplicate_move_linked()

    bpy.context.window_manager.progress_end()

    return (L)
def add_lattice_vectors(self, a0, a1, a2, name='lattice_vectors', shift_origin=False, cone_length=None, cone_radius=None, cylinder_radius=None):
  
  loadBasicMaterials()
  
  a0 = Vector(a0)
  a1 = Vector(a1)
  a2 = Vector(a2)
  centro = 0.5*(a0+a1+a2)
  
  if shift_origin:
    start_point = -centro
  else:
    start_point = Vector([0,0,0])
  
  # get shortest arrow length
  arrow_length = min(a0.length, a1.length, a2.length)
  if not cone_length:
    cone_length = arrow_length/5.0
  if not cone_radius:
    cone_radius = arrow_length/20.0
  if not cylinder_radius:
    cylinder_radius = cone_radius/2.0
  
  obj_a0 = add_arrow(self, start_point, start_point+a0, name='a0', cone_length=cone_length, cone_radius=cone_radius, cylinder_radius=cylinder_radius)
  bpy.ops.object.material_slot_add()
  obj_a0.material_slots[obj_a0.material_slots.__len__() - 1].material = bpy.data.materials['red']

  obj_a1 = add_arrow(self, start_point, start_point+a1, name='a1', cone_length=cone_length, cone_radius=cone_radius, cylinder_radius=cylinder_radius)
  bpy.ops.object.material_slot_add()
  obj_a1.material_slots[obj_a1.material_slots.__len__() - 1].material = bpy.data.materials['green']

  obj_a2 = add_arrow(self, start_point, start_point+a2, name='a2', cone_length=cone_length, cone_radius=cone_radius, cylinder_radius=cylinder_radius)
  bpy.ops.object.material_slot_add()
  obj_a2.material_slots[obj_a2.material_slots.__len__() - 1].material = bpy.data.materials['blue']
  
  bpy.ops.object.add(type='EMPTY')
  obj_empty = bpy.context.active_object
  obj_empty.name = name
  selectObjects([obj_empty, obj_a0, obj_a1, obj_a2], active_object=obj_empty, context = bpy.context)
  bpy.ops.object.parent_set(type='OBJECT', keep_transform=True)
  
  return (obj_empty, obj_a0, obj_a1, obj_a2)
def add_photonic_wire(self, context):
  
  blender_object_list = []
  if self.show_design:
    cyl = GeometryObjects.add_cylinder(self, [-0.5*self.length, 0, self.height + self.bend_radius], [0.5*self.length, 0, self.height + self.bend_radius], name='photonic wire', cylinder_radius=0.5*self.wire_diametre)
    cone1 = GeometryObjects.add_cone(self, [-0.5*self.length-self.bend_radius, 0, 0], [-0.5*self.length-self.bend_radius, 0, self.height], name='Cone1', radius1=0.5*self.cone_diametre, radius2=0.5*self.wire_diametre)
    cone2 = GeometryObjects.add_cone(self, [0.5*self.length+self.bend_radius, 0, 0], [0.5*self.length+self.bend_radius, 0, self.height], name='Cone2', radius1=0.5*self.cone_diametre, radius2=0.5*self.wire_diametre)
    bend1 = GeometryObjects.add_bend(centre=[0.5*self.length, 0, self.height], bend_radius=self.bend_radius, tube_radius=0.5*self.wire_diametre, name='bend2', angle_start_deg=0, angle_end_deg=90)
    bend2 = GeometryObjects.add_bend(centre=[-0.5*self.length, 0, self.height], bend_radius=self.bend_radius, tube_radius=0.5*self.wire_diametre, name='bend1', angle_start_deg=90, angle_end_deg=180)
    
    blender_object_list.extend([cyl, cone1, cone2, bend1, bend2])
    
  if self.show_gwl:
    a = GeometryObjects.add_gwl_cone(self, [-0.5*self.length-self.bend_radius, 0, 0], [-0.5*self.length-self.bend_radius, 0, self.height], name='GWL_wire0_Cone1', radius1=0.5*self.cone_diametre, radius2=0.5*self.wire_diametre,
      cross_section_r0=self.cross_section_r0, cross_section_delta_r=self.cross_section_delta_r, cross_section_delta_theta=self.cross_section_delta_theta, longitudinal_delta=self.cone_delta)
    b = GeometryObjects.add_gwl_bend(centre=[-0.5*self.length, 0, self.height], bend_radius=self.bend_radius, tube_radius=0.5*self.wire_diametre, name='GWL_wire1_bend1', angle_start_deg=180, angle_end_deg=90,
      cross_section_r0=self.cross_section_r0, cross_section_delta_r=self.cross_section_delta_r, cross_section_delta_theta=self.cross_section_delta_theta, longitudinal_delta=self.bend_delta)
    c = GeometryObjects.add_gwl_cylinder(self, [-0.5*self.length, 0, self.height + self.bend_radius], [0.5*self.length, 0, self.height + self.bend_radius], name='GWL_wire2_photonic_wire', cylinder_radius=0.5*self.wire_diametre,
      cross_section_r0=self.cross_section_r0, cross_section_delta_r=self.cross_section_delta_r, cross_section_delta_theta=self.cross_section_delta_theta, longitudinal_delta=self.wire_delta)
    d = GeometryObjects.add_gwl_bend(centre=[0.5*self.length, 0, self.height], bend_radius=self.bend_radius, tube_radius=0.5*self.wire_diametre, name='GWL_wire3_bend2', angle_start_deg=90, angle_end_deg=0,
      cross_section_r0=self.cross_section_r0, cross_section_delta_r=self.cross_section_delta_r, cross_section_delta_theta=self.cross_section_delta_theta, longitudinal_delta=self.bend_delta)
    e = GeometryObjects.add_gwl_cone(self, [0.5*self.length+self.bend_radius, 0, self.height], [0.5*self.length+self.bend_radius, 0, 0], name='GWL_wire4_Cone2', radius2=0.5*self.cone_diametre, radius1=0.5*self.wire_diametre,
      cross_section_r0=self.cross_section_r0, cross_section_delta_r=self.cross_section_delta_r, cross_section_delta_theta=self.cross_section_delta_theta, longitudinal_delta=self.cone_delta)
  
    blender_object_list.extend([a,b,c,d,e])
    
  if blender_object_list:
    selectObjects(blender_object_list)
    bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
    bpy.ops.object.parent_to_empty()
    obj = bpy.context.active_object
    obj.matrix_world = Matrix.Rotation(radians(self.rotation), 4, 'Z')
    obj.location = self.location
  
  # for obj in blender_object_list:
    # # setOrigin(obj, [0,0,0])
    # # obj.rotation_euler = (0,0,0)  # Note that you need to use radians rather than angles here
    
    # obj.matrix_world = Matrix.Rotation(radians(self.rotation), 4, 'Z')
    # obj.location = self.location
    
  return
def add_photonic_torus(self, context):

    blender_object_list = []
    if self.show_design:
        b = GeometryObjects.add_bend(centre=[0, 0, 0],
                                     bend_radius=self.bend_radius,
                                     tube_radius=0.5 * self.wire_diametre,
                                     name='bend_design',
                                     angle_start_deg=self.angle_start_deg,
                                     angle_end_deg=self.angle_end_deg)

        blender_object_list.extend([b])

    if self.show_gwl:
        b = GeometryObjects.add_gwl_bend(
            centre=[0, 0, 0],
            bend_radius=self.bend_radius,
            tube_radius=0.5 * self.wire_diametre,
            name='bend_GWL',
            angle_start_deg=self.angle_start_deg,
            angle_end_deg=self.angle_end_deg,
            cross_section_r0=self.cross_section_r0,
            cross_section_delta_r=self.cross_section_delta_r,
            cross_section_delta_theta=self.cross_section_delta_theta,
            longitudinal_delta=self.bend_delta)

        blender_object_list.extend([b])

    if blender_object_list:
        selectObjects(blender_object_list)
        bpy.ops.object.transform_apply(location=True,
                                       rotation=True,
                                       scale=True)
        bpy.ops.object.parent_to_empty()
        obj = bpy.context.active_object
        obj.matrix_world = Matrix.Rotation(radians(self.rotation), 4, 'Z')
        obj.location = self.location

    return
    def createBlenderObject(self, blender_operator, context):
        import bpy
        from blender_scripts.modules.GeometryObjects import add_cylinder, add_tetra, add_block
        from blender_scripts.modules.blender_utilities import selectObjects

        cursor_location3 = numpy.array(bpy.context.scene.cursor_location)

        bpy.ops.mesh.primitive_cylinder_add(radius=0.5 * self.disk_diametro,
                                            depth=self.disk_height)
        obj_disk = bpy.context.active_object
        obj_disk.name = 'CBD.disk'

        obj_wall_top = add_block(
            blender_operator,
            location3=numpy.array([0, 0.5 * self.getDiskDiametro(), 0]),
            size3=[
                self.getDiskDiametro() + 2 * self.getWallLengthExtra(),
                self.getWallWidth(),
                self.getDiskHeight() + 2 * self.getWallHeightExtra()
            ],
            name='CBD.wall_top')
        obj_wall_top.parent = obj_disk

        obj_wall_bottom = add_block(
            blender_operator,
            location3=-numpy.array([0, 0.5 * self.getDiskDiametro(), 0]),
            size3=[
                self.getDiskDiametro() + 2 * self.getWallLengthExtra(),
                self.getWallWidth(),
                self.getDiskHeight() + 2 * self.getWallHeightExtra()
            ],
            name='CBD.wall_bottom')
        obj_wall_bottom.parent = obj_disk

        obj_hole = add_block(blender_operator,
                             location3=cursor_location3,
                             size3=[
                                 self.getHoleWidth(),
                                 self.getHoleLength(),
                                 2 * self.getDiskHeight()
                             ],
                             name='CBD.hole')
        #obj_hole.parent = obj_disk

        bool_mod = obj_disk.modifiers.new('CBD.hole-modifier', 'BOOLEAN')
        bool_mod.operation = 'DIFFERENCE'
        bool_mod.object = obj_hole
        #obj_hole.hide = True

        selectObjects([obj_disk], active_object=obj_disk, context=bpy.context)
        bpy.ops.object.modifier_apply(modifier=bool_mod.name, apply_as='DATA')

        selectObjects([obj_hole], active_object=obj_hole, context=bpy.context)
        bpy.ops.object.delete()

        selectObjects([obj_disk], active_object=obj_disk, context=bpy.context)

        return (obj_disk)
예제 #6
0
    def execute(self, context):
      
      # .. todo:: Support rotation as usual in object addons?
      # crystal axes
      e1 = [1,0,0]
      e2 = [0,1,0]
      e3 = [0,0,1]
      
      if self.cell_type == 'RCD':
        # .. todo:: set to cursor location (check how addCube & co initialize it -> It is set when object_data_add(context, mesh, operator=self) is called, which means ideally a mesh should be created and then passed to that function. It should take care of rotation&co too.)
        ## get cursor location for placement
        #cursor_location3 = numpy.array(bpy.context.scene.cursor_location)
        #self.setLocation(cursor_location3)
      
        location = Vector(self.location)
        
        obj_list = []
        if self.shift_cell:
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([3/4, 1/4, 1/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([1/4, 3/4, 1/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([1/4, 1/4, 3/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([3/4, 3/4, 3/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
        else:
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([1/4, 1/4, 1/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([3/4, 3/4, 1/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([3/4, 1/4, 3/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
          obj_list.extend( add_tetra(self, location=location+self.size*Vector([1/4, 3/4, 3/4]), size=self.size/2, name='Tetra', cylinder_radius=self.radius) )
        
        common_mesh = obj_list[0].data
        for obj in obj_list[1:]:
          obj.data = common_mesh
          
        selectObjects(obj_list)
        bpy.ops.object.join()
        obj_blender = context.active_object
        obj_blender.name='RCD'
        setOrigin(obj_blender, self.location)
        bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)
        
        e1 = self.size*Vector([1,0,0])
        e2 = self.size*Vector([0,1,0])
        e3 = self.size*Vector([0,0,1])
      elif self.cell_type == 'RCD111_inverse':
        if self.shift_cell:
          STLfile = os.path.join(pathlib.Path.home(), 'Development/script_inception_public/src/blender_scripts/STL-files/RCD111_inverse_shifted_centred.stl')
        else:
          STLfile = os.path.join(pathlib.Path.home(), 'Development/script_inception_public/src/blender_scripts/STL-files/RCD111_inverse.stl')
        objName = bpy.path.display_name(os.path.basename(STLfile))
        tris, tri_nors, pts = stl_utils.read_stl(STLfile)
        tri_nors = None
        axis_forward='Y'
        axis_up='Z'
        global_scale = 1
        global_matrix = axis_conversion(from_forward=axis_forward, from_up=axis_up).to_4x4() * Matrix.Scale(global_scale, 4)
        print(global_matrix)
        blender_utils.create_and_link_mesh(objName, tris, tri_nors, pts, global_matrix)
        obj_blender = context.active_object
        
        # get cursor location for placement
        obj_blender.location = numpy.array(bpy.context.scene.cursor_location)
        
        obj_bfdtd = bfdtd.RCD.RCD_HexagonalLattice()
        obj_bfdtd.setOuterRadius(self.radius)
        obj_bfdtd.setCubicUnitCellSize(self.size)
        obj_bfdtd.setShifted(self.shift_cell)
        obj_bfdtd.setUnitCellType(2)
        e1, e2, e3 = obj_bfdtd.getLatticeVectors()
        
      else:
        if 'RCD111' in self.cell_type:
          obj_bfdtd = bfdtd.RCD.RCD_HexagonalLattice()
        else:
          obj_bfdtd = bfdtd.RCD.FRD_HexagonalLattice()
        obj_bfdtd.setOuterRadius(self.radius)
        obj_bfdtd.setCubicUnitCellSize(self.size)
        obj_bfdtd.setShifted(self.shift_cell)
        if 'v1' in self.cell_type:
          obj_bfdtd.setUnitCellType(1)
        else:
          obj_bfdtd.setUnitCellType(2)

        if self.RCD111_v2_advanced:
          obj_bfdtd.fillBox(self.RCD111_v2_location, self.RCD111_v2_size)
          # obj_bfdtd.fillBox([self.RCD111_v2_Nx, self.RCD111_v2_Ny, self.RCD111_v2_Nz], [self.RCD111_v2_Nx, self.RCD111_v2_Ny, self.RCD111_v2_Nz])
          # obj_bfdtd.createRectangularArraySymmetrical(self.RCD111_v2_Nx, self.RCD111_v2_Ny, self.RCD111_v2_Nz)
          add_block(self, location3 = self.RCD111_v2_location, size3 = self.RCD111_v2_size, name='box_to_fill', wiremode=True)
        
        obj_blender = obj_bfdtd.createBlenderObject(self, context)
        e1, e2, e3 = obj_bfdtd.getLatticeVectors()
        
      obj_blender.name = self.cell_type
      if self.create_array:
        add_array_modifier(obj_blender, 'array-modifier-X', self.array_size_X, e1)
        add_array_modifier(obj_blender, 'array-modifier-Y', self.array_size_Y, e2)
        add_array_modifier(obj_blender, 'array-modifier-Z', self.array_size_Z, e3)

      # add unit-cell bounding box
      if self.add_unit_cell_BB:
        obj_lattice_cell = add_lattice_cell(self, e1, e2, e3, name='lattice_cell', shift_origin=self.shift_origin, wiremode=True)
        selectObjects([obj_blender, obj_lattice_cell], active_object=obj_lattice_cell, context = context)
        bpy.ops.object.parent_set(type='OBJECT', keep_transform=False)

      return {'FINISHED'}
  def execute(self):
    print("running read_mpb...")
    filepath_basename = os.path.basename(self.filepath)
    with open(self.filepath) as infile:
      MPB_data_list = parse_MPB(infile)
      
      for idx, MPB_data_object in enumerate(MPB_data_list):
        print('=== dataset {} ==='.format(idx))
        
        name = 'k-points-{}-{}'.format(filepath_basename, idx)
        
        # add lattice+reciprocal lattice basis vectors+cells
        (a0,a1,a2) = MPB_data_object.getLatticeVectors()
        (b0,b1,b2) = MPB_data_object.getReciprocalLatticeVectors()
        
        add_lattice_objects(self, a0, a1, a2, b0, b1, b2, name = name+'-lattice_objects',
                            cone_length=self.cone_length,
                            cone_radius=self.cone_radius,
                            cylinder_radius=self.cylinder_radius)
        
        # add k-point path and sphere following it
        L = MPB_data_object.get_kpoints_in_cartesian_coordinates()
        if len(L)>0:
          for i in L:
            print(i)
          
          mesh = bpy.data.meshes.new(name)

          bm = bmesh.new()

          for v_co in L:
            bm.verts.new(v_co)

          bm.verts.ensure_lookup_table()
          for i in range(len(L)-1):
            bm.edges.new([bm.verts[i], bm.verts[i+1]])

          bm.to_mesh(mesh)
          mesh.update()

          object_data_add(self.context, mesh, operator=self.operator)
          bpy.ops.object.convert(target='CURVE')
          
          k_points_path_object = self.context.active_object
          k_points_path_object.name = name+'-path'

          print('Adding animation...')
          k_points_path_object.data.use_path = True
          scene = self.context.scene
          k_points_path_object.data.path_duration = scene.frame_end - scene.frame_start

          bpy.ops.mesh.primitive_uv_sphere_add()
          S = self.context.active_object
          S.name = name+'-sphere'
          L = numpy.power(MPB_data_object.getReciprocalCellVolume(), 1/3)
          S.scale = 3*[L/20]

          # add a constraint to it
          constraint = S.constraints.new('FOLLOW_PATH')
          constraint.target = k_points_path_object

          #bpy.ops.object.constraint_add(type='FOLLOW_PATH')
          #C = S.constraints[-1]
          #C.target = k_points_path_object
          #selectObjects([S], active_object=S, context=self.context)
          #bpy.ops.constraint.followpath_path_animate(constraint="Follow Path", owner='OBJECT')

          override = {'constraint':constraint}
          bpy.ops.constraint.followpath_path_animate(override,constraint='Follow Path')

          selectObjects([k_points_path_object], active_object=k_points_path_object, context=self.context)

        else:
          print('no k-points found')

    print('FINISHED')
    return {'FINISHED'}
예제 #8
0
    def importBristolFDTD_single_file(self,
                                      filename,
                                      filename_idx=None,
                                      prefix_zfill=0):
        '''
      Import BristolFDTD geometry from .in,.geo or .inp and create corresponding structure in Blender.
      
      This function imports a single file.
      To import multiple files, use :py:func:`importBristolFDTD`
      '''

        start_time = time.time()

        print('----->Importing bristol FDTD geometry: ' + filename)
        print(self.PrintSelf('\t'))

        #Blender.Window.WaitCursor(1);

        # save import path
        # Blender.Set('tempdir',os.path.dirname(filename));
        #FILE = open(, 'w');
        #pickle.dump(, FILE);
        #FILE.close();

        with open(cfgfile, 'wb') as f:
            # Pickle the 'data' dictionary using the highest protocol available.
            pickle.dump(filename, f, pickle.HIGHEST_PROTOCOL)

        # create structured_entries
        structured_entries = readBristolFDTD(filename)

        ##################
        # GROUP SETUP
        ##################
        # create group corresponding to this file
        # deselect all
        bpy.ops.object.select_all(action='DESELECT')

        # Truncated to 63 characters because that seems to be the maximum string length Blender accepts for group names.
        # (allows keeping part of the path for better identification if multiple files use the same basename)
        if filename_idx is None:
            group_name = filename[-63:]
        else:
            group_name_prefix = str(filename_idx).zfill(prefix_zfill) + '-'
            group_name = group_name_prefix + filename[-(
                63 - len(group_name_prefix)):]

        #if group_name in bpy.data.groups:
        #raise Exception('group already exists: {}\n{}'.format(group_name, bpy.data.groups))

        # older version
        #bpy.ops.group.create(name=group_name)
        # This version ensures that a new group name is created if necessary and stores the new group in *current_group*.
        # current_group = bpy.data.groups.new(name=group_name) # blender<2.8
        # group_name = current_group.name # blender<2.8
        collection_current_file = blender_utilities.make_collection(
            group_name)  # blender>=2.8

        collection_meshes = blender_utilities.make_collection('meshes')
        collection_boxes = blender_utilities.make_collection('boxes')
        collection_excitations = blender_utilities.make_collection(
            'excitations')
        collection_frequencySnapshots = blender_utilities.make_collection(
            'frequencySnapshots')
        collection_timeSnapshots = blender_utilities.make_collection(
            'timeSnapshots')
        collection_epsilonSnapshots = blender_utilities.make_collection(
            'epsilonSnapshots')
        collection_spheres = blender_utilities.make_collection('spheres')
        collection_distorted = blender_utilities.make_collection('distorted')
        collection_blocks = blender_utilities.make_collection('blocks')
        collection_cylinders = blender_utilities.make_collection('cylinders')
        collection_probes = blender_utilities.make_collection('probes')
        ##################

        # we create an instance of the FDTDGeometryObjects class, which allows adding objects to the scene with shared materials (TODO: maybe find a better system?)
        FDTDGeometryObjects_obj = FDTDGeometryObjects()

        # Blender.Window.RedrawAll(); # This must be called before any SetActiveLayer calls!

        layerManager = LayerManagerObjects()

        # Box
        #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('box'));
        obj = FDTDGeometryObjects_obj.GEObox(
            structured_entries.box.name, Vector(structured_entries.box.lower),
            Vector(structured_entries.box.upper))
        blender_utilities.setActiveObject(obj)
        # if bpy.app.version >= (2, 8, 0):
        # bpy.context.view_layer.objects.active = obj
        # else:
        # bpy.context.scene.objects.active = obj

        # if bpy.app.version >= (2, 8, 0):
        blender_utilities.addToCollection(obj,
                                          group_name,
                                          removeFromOthers=False)
        blender_utilities.addToCollection(obj, 'boxes', removeFromOthers=False)

        # blender_utilities.addToCollection(obj, 'cylinders', removeFromOthers=False)
        # blender_utilities.addToCollection(obj, 'cylinders', removeFromOthers=False)
        # blender_utilities.addToCollection(obj, 'probes', removeFromOthers=False)
        # blender_utilities.addToCollection(obj, collection_probes, removeFromOthers=False)
        # blender_utilities.addToCollection(obj, collection_spheres, removeFromOthers=True)
        # else:
        # bpy.ops.object.group_link(group=group_name)
        # bpy.ops.object.group_link(group='boxes')

        # mesh
        #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('mesh'));
        #FDTDGeometryObjects_obj.GEOmesh('mesh', False, structured_entries.delta_X_vector,structured_entries.delta_Y_vector,structured_entries.delta_Z_vector);
        #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('mesh'));
        obj = FDTDGeometryObjects_obj.GEOmesh(
            'mesh', False, structured_entries.mesh.getXmeshDelta(),
            structured_entries.mesh.getYmeshDelta(),
            structured_entries.mesh.getZmeshDelta())
        blender_utilities.setActiveObject(obj, context=bpy.context)

        blender_utilities.addToCollection(obj,
                                          group_name,
                                          removeFromOthers=False)
        blender_utilities.addToCollection(obj,
                                          'meshes',
                                          removeFromOthers=False)

        # Time_snapshot (time or EPS)
        Ntsnaps = 0
        for time_snapshot in structured_entries.time_snapshot_list:

            Ntsnaps += 1
            snap_plane = time_snapshot.getPlaneLetter()
            probe_ident = structured_entries.flag.id_string.replace('\"', '')
            snap_time_number = 1
            TimeSnapshotFileName, alphaID, pair = brisFDTD_ID_info.numID_to_alphaID_TimeSnapshot(
                Ntsnaps, snap_plane, probe_ident, snap_time_number)

            if time_snapshot.eps == 0:
                #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('time_snapshots_'+planeNumberName(time_snapshot.plane)[1]))
                obj = FDTDGeometryObjects_obj.GEOtime_snapshot(
                    time_snapshot.name, time_snapshot.getPlaneLetter(),
                    time_snapshot.P1, time_snapshot.P2)
                blender_utilities.setActiveObject(obj, context=bpy.context)
                blender_utilities.addToCollection(obj,
                                                  group_name,
                                                  removeFromOthers=False)
                blender_utilities.addToCollection(obj,
                                                  'timeSnapshots',
                                                  removeFromOthers=False)
            else:
                #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('eps_snapshots_'+planeNumberName(time_snapshot.plane)[1]))

                obj = FDTDGeometryObjects_obj.GEOeps_snapshot(
                    TimeSnapshotFileName, time_snapshot.getPlaneLetter(),
                    time_snapshot.P1, time_snapshot.P2)
                #obj = FDTDGeometryObjects_obj.GEOeps_snapshot(time_snapshot.name, time_snapshot.plane, time_snapshot.P1, time_snapshot.P2)

                blender_utilities.setActiveObject(obj, context=bpy.context)
                blender_utilities.addToCollection(obj,
                                                  group_name,
                                                  removeFromOthers=False)
                blender_utilities.addToCollection(obj,
                                                  'epsilonSnapshots',
                                                  removeFromOthers=False)

        # Frequency_snapshot
        # TODO: Finally get a correct system for filenames/comment names/etc implemented. getfilename() or something...
        Nfsnaps = 0
        for frequency_snapshot in structured_entries.frequency_snapshot_list:
            #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('frequency_snapshots_'+planeNumberName(frequency_snapshot.plane)[1]));

            Nfsnaps += 1
            snap_plane = frequency_snapshot.getPlaneLetter()
            probe_ident = structured_entries.flag.id_string.replace('\"', '')
            snap_time_number = 0
            FrequencySnapshotFileName, alphaID, pair = brisFDTD_ID_info.numID_to_alphaID_FrequencySnapshot(
                Nfsnaps,
                snap_plane,
                probe_ident,
                snap_time_number,
                pre_2008_BFDTD_version=self.pre_2008_BFDTD_version)

            obj = FDTDGeometryObjects_obj.GEOfrequency_snapshot(
                FrequencySnapshotFileName, frequency_snapshot.getPlaneLetter(),
                frequency_snapshot.P1, frequency_snapshot.P2)
            #obj = FDTDGeometryObjects_obj.GEOfrequency_snapshot(frequency_snapshot.name, frequency_snapshot.plane, frequency_snapshot.P1, frequency_snapshot.P2)

            blender_utilities.setActiveObject(obj, context=bpy.context)
            blender_utilities.addToCollection(obj,
                                              group_name,
                                              removeFromOthers=False)
            blender_utilities.addToCollection(obj,
                                              'frequencySnapshots',
                                              removeFromOthers=False)

        # Excitation
        #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('excitations'));
        for excitation in structured_entries.excitation_list:
            #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('excitations'));
            #print(Blender.Window.GetActiveLayer())
            #print(excitation)
            obj = FDTDGeometryObjects_obj.GEOexcitation(excitation)
            blender_utilities.setActiveObject(obj, context=bpy.context)
            blender_utilities.addToCollection(obj,
                                              group_name,
                                              removeFromOthers=False)
            blender_utilities.addToCollection(obj,
                                              'excitations',
                                              removeFromOthers=False)
            #FDTDGeometryObjects_obj.GEOexcitation(excitation.name, Vector(excitation.P1), Vector(excitation.P2));
        # Probe
        #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('probes'));
        Nprobes = 0
        for probe in structured_entries.probe_list:
            # print('probe = ',Vector(probe.position))
            Nprobes += 1
            ProbeFileName = 'p' + str(
                Nprobes).zfill(2) + structured_entries.flag.id_string.replace(
                    '\"', '') + '.prn'
            #FDTDGeometryObjects_obj.GEOprobe(probe.name+' ('+ProbeFileName+')', Vector(probe.position));
            obj = FDTDGeometryObjects_obj.GEOprobe(ProbeFileName,
                                                   Vector(probe.position))
            blender_utilities.setActiveObject(obj, context=bpy.context)
            blender_utilities.addToCollection(obj,
                                              group_name,
                                              removeFromOthers=False)
            blender_utilities.addToCollection(obj,
                                              'probes',
                                              removeFromOthers=False)

        ##################################################################
        ### geometry loading

        if not self.no_geometry:

            if self.create_vertex_mesh:

                # just create a mesh of vertices representing object locations
                # .. todo:: just as with the lines for cylinders, this should be an option for spheres (i.e. different placeholders for each type of object) (also create different vertex mesh for each "material"/.geo file)

                L = structured_entries.getGeometryObjects()
                N = len(L)
                print('N(objects) = {}'.format(N))

                verts = N * [Vector((0, 0, 0))]

                for idx, obj in enumerate(L):
                    verts[idx] = Vector(obj.getLocation())

                edges = []
                faces = []

                mesh = bpy.data.meshes.new(name="Object positions")
                mesh.from_pydata(verts, edges, faces)
                #object_data_add(bpy.context, mesh, operator=self)
                object_data_add(bpy.context, mesh)

            else:
                # Sphere
                #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('spheres'));
                for sphere in structured_entries.sphere_list:
                    # variables
                    centro = Vector(sphere.getLocation())

                    # initialise rotation_matrix
                    rotation_matrix = Matrix()
                    rotation_matrix.identity()

                    # scale object
                    #Sx=Blender.Mathutils.ScaleMatrix(abs(2*sphere.outer_radius),4,Blender.Mathutils.Vector(1,0,0))
                    #Sy=Blender.Mathutils.ScaleMatrix(abs(2*sphere.outer_radius),4,Blender.Mathutils.Vector(0,1,0))
                    #Sz=Blender.Mathutils.ScaleMatrix(abs(2*sphere.outer_radius),4,Blender.Mathutils.Vector(0,0,1))
                    #rotation_matrix *= Sx*Sy*Sz;

                    # position object
                    #T = Blender.Mathutils.TranslationMatrix(centro)
                    #rotation_matrix *= T;

                    # add rotations
                    #for r in sphere.rotation_list:
                    #rotation_matrix *= rotationMatrix(r.axis_point, r.axis_direction, r.angle_degrees);

                    # create object
                    obj = FDTDGeometryObjects_obj.GEOsphere(
                        sphere.name, sphere.getLocation(), sphere.outer_radius,
                        sphere.inner_radius, sphere.permittivity,
                        sphere.conductivity)
                    #FDTDGeometryObjects_obj.GEOsphere_matrix(sphere.name, rotation_matrix, sphere.outer_radius, sphere.inner_radius, sphere.permittivity, sphere.conductivity);
                    #FDTDGeometryObjects_obj.GEOblock_matrix(sphere.name, rotation_matrix, sphere.permittivity, sphere.conductivity);
                    blender_utilities.setActiveObject(obj, context=bpy.context)
                    blender_utilities.addToCollection(obj,
                                                      group_name,
                                                      removeFromOthers=False)
                    blender_utilities.addToCollection(obj,
                                                      'spheres',
                                                      removeFromOthers=False)

                if self.import_blocks:
                    # Block
                    #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('blocks'))
                    for block in structured_entries.block_list:
                        # variables
                        lower = Vector(block.getLowerAbsolute())
                        upper = Vector(block.getUpperAbsolute())
                        pos = 0.5 * (lower + upper)
                        diag = 0.5 * (upper - lower)

                        # initialise rotation_matrix
                        rotation_matrix = Matrix()
                        rotation_matrix.identity()

                        # add rotations
                        for r in block.rotation_list:
                            rotation_matrix = rotationMatrix(
                                r.axis_point, r.axis_direction,
                                r.angle_degrees) * rotation_matrix

                        # position object
                        T = Matrix.Translation(pos)
                        if bpy.app.version >= (2, 8, 0):
                            rotation_matrix @= T
                        else:
                            rotation_matrix *= T

                        ## scale object
                        Sx = Matrix.Scale(abs(diag[0]), 4, Vector((1, 0, 0)))
                        Sy = Matrix.Scale(abs(diag[1]), 4, Vector((0, 1, 0)))
                        Sz = Matrix.Scale(abs(diag[2]), 4, Vector((0, 0, 1)))
                        if bpy.app.version >= (2, 8, 0):
                            rotation_matrix @= Sx @ Sy @ Sz
                        else:
                            rotation_matrix *= Sx * Sy * Sz

                        # create object
                        obj = FDTDGeometryObjects_obj.GEOblock_matrix(
                            block.name, rotation_matrix, block.permittivity,
                            block.conductivity)
                        #FDTDGeometryObjects_obj.GEOblock(block.name, block.lower, block.upper, block.permittivity, block.conductivity)
                        blender_utilities.setActiveObject(obj,
                                                          context=bpy.context)
                        blender_utilities.addToCollection(
                            obj, group_name, removeFromOthers=False)
                        blender_utilities.addToCollection(
                            obj, 'blocks', removeFromOthers=False)

                # Distorted
                for distorted in structured_entries.distorted_list:
                    # create object
                    #print(distorted)
                    obj = FDTDGeometryObjects_obj.GEOdistorted(distorted)
                    blender_utilities.setActiveObject(obj, context=bpy.context)
                    blender_utilities.addToCollection(obj,
                                                      group_name,
                                                      removeFromOthers=False)
                    #bpy.ops.object.group_link(group=type(distorted).__name__)
                    blender_utilities.addToCollection(obj,
                                                      'distorted',
                                                      removeFromOthers=False)

                #########################
                # Cylinders

                if self.import_cylinders:

                    if self.cylinder_to_line_mesh:
                        createLineMeshFromCylinders(structured_entries)
                    else:
                        ## progress indicator does not work when running from CLI
                        if self.GUI_loaded:
                            bpy.context.window_manager.progress_begin(0, 100)

                        #Blender.Window.SetActiveLayer(1<<layerManager.DefaultLayers.index('cylinders'));

                        if self.restrict_import_volume:
                            if self.volume_specification_style == 'relative':
                                import_volume_xmin = self.xmin * structured_entries.getSize(
                                )[0]
                                import_volume_xmax = self.xmax * structured_entries.getSize(
                                )[0]
                                import_volume_ymin = self.ymin * structured_entries.getSize(
                                )[1]
                                import_volume_ymax = self.ymax * structured_entries.getSize(
                                )[1]
                                import_volume_zmin = self.zmin * structured_entries.getSize(
                                )[2]
                                import_volume_zmax = self.zmax * structured_entries.getSize(
                                )[2]
                            else:
                                import_volume_xmin = self.xmin
                                import_volume_xmax = self.xmax
                                import_volume_ymin = self.ymin
                                import_volume_ymax = self.ymax
                                import_volume_zmin = self.zmin
                                import_volume_zmax = self.zmax

                            truncated_cylinder_list = truncateGeoList(
                                structured_entries.cylinder_list,
                                import_volume_xmin, import_volume_xmax,
                                import_volume_ymin, import_volume_ymax,
                                import_volume_zmin, import_volume_zmax)
                            if self.verbosity > 0:
                                print(self)
                                print(
                                    'len(structured_entries.cylinder_list) = {}'
                                    .format(
                                        len(structured_entries.cylinder_list)))
                                print(
                                    'len(truncated_cylinder_list) = {}'.format(
                                        len(truncated_cylinder_list)))
                        else:
                            truncated_cylinder_list = structured_entries.cylinder_list

                        if self.use_Nmax_objects:
                            truncated_cylinder_list = truncated_cylinder_list[:
                                                                              self
                                                                              .
                                                                              Nmax_objects]

                        # hack to create a lot of objects quickly using duplication.
                        # .. todo:: replace/improve + implement for other objects
                        # .. todo:: one mesh per material & .geo file, rather than multiple objects, while respecting appearance order, i.e. group sequences of same material objects into a single mesh.
                        # cf:
                        #   https://blender.stackexchange.com/questions/7358/python-performance-with-blender-operators
                        #   https://blender.stackexchange.com/questions/39721/how-can-i-create-many-objects-quickly

                        N = len(truncated_cylinder_list)
                        if self.verbosity > 0:
                            print(
                                'len(truncated_cylinder_list) = {}'.format(N))
                        if N > 0:
                            N_added_max = 500
                            N_added = min(N_added_max, N)
                            N_duplications = (N // N_added) - 1
                            N_remainder = N % N_added

                            print('N', N)
                            print('N_added_max', N_added_max)
                            print('N_added', N_added)
                            print('N_duplications', N_duplications)
                            print('N_remainder', N_remainder)
                            print('total = ' +
                                  str(N_added + N_duplications * N_added +
                                      N_remainder))

                            Nfill = len(str(N))

                            cyl_list = N * [0]

                            # add all cylinders
                            print('Adding all ' + str(N) + ' cylinders...')

                            # normal add
                            if self.GUI_loaded:
                                bpy.context.window_manager.progress_update(0)
                            for i in range(N_added + N_remainder):
                                bpy.ops.mesh.primitive_cylinder_add(
                                    location=Vector([0, 0, 0]),
                                    rotation=(radians(-90), 0, 0))
                                bpy.ops.object.transform_apply(
                                    rotation=True
                                )  # aligning cylinder to Y axis directly and applying rotation, to follow BFDTD standard cylinder orientation.
                                cyl_list[i] = bpy.context.object
                                if self.GUI_loaded:
                                    bpy.context.window_manager.progress_update(
                                        i / (N_added + N_remainder))

                            ## select items to duplicate
                            selectObjects(cyl_list[0:N_added])

                            ## duplicate
                            if self.GUI_loaded:
                                bpy.context.window_manager.progress_update(0)
                            for i in range(N_duplications):
                                #'cyl.''{:0>-{Nfill}}'.format(i,Nfill=Nfill)
                                bpy.ops.object.duplicate_move_linked()
                                start_idx = N_added + N_remainder + i * N_added
                                end_idx = start_idx + N_added
                                print((start_idx, end_idx))
                                cyl_list[
                                    start_idx:
                                    end_idx] = bpy.context.selected_objects
                                if self.GUI_loaded:
                                    bpy.context.window_manager.progress_update(
                                        i / N_duplications)

                            # set location/rotation/scale of cylinders
                            print('Setting location/rotation/scale of all ' +
                                  str(N) + ' cylinders...')
                            #for i, cylinder in enumerate(truncated_cylinder_list):
                            #obj = cyl_list[i]

                            if self.GUI_loaded:
                                bpy.context.window_manager.progress_update(0)
                            for i, cylinder in enumerate(
                                    truncated_cylinder_list):
                                #for cylinder in truncated_cylinder_list:

                                # initialise rotation_matrix
                                rotation_matrix = Matrix()
                                rotation_matrix.identity()

                                scale = [
                                    cylinder.outer_radius,
                                    cylinder.outer_radius,
                                    0.5 * cylinder.height
                                ]

                                Sx = Matrix.Scale(scale[0], 4, [1, 0, 0])
                                Sy = Matrix.Scale(scale[1], 4, [0, 1, 0])
                                Sz = Matrix.Scale(scale[2], 4, [0, 0, 1])

                                #rotation_matrix *= Sx*Sy*Sz;

                                # add rotations
                                # TODO: Check it works correctly...
                                for r in cylinder.rotation_list:
                                    rotation_matrix *= rotationMatrix(
                                        r.axis_point, r.axis_direction,
                                        r.angle_degrees) * rotation_matrix

                                #r = cylinder.rotation_list[0]

                                # position object
                                T = Matrix.Translation(
                                    Vector([
                                        cylinder.location[0],
                                        cylinder.location[1],
                                        cylinder.location[2]
                                    ]))
                                rotation_matrix *= T

                                # because FDTD cylinders are aligned with the Y axis by default
                                #rotation_matrix *= rotationMatrix(Vector([0,0,0]), Vector([1,0,0]), -90)

                                # create object
                                #obj = FDTDGeometryObjects_obj.GEOcylinder_matrix(cylinder.name, rotation_matrix, cylinder.inner_radius, cylinder.outer_radius, cylinder.height, cylinder.permittivity, cylinder.conductivity)
                                #obj = cyl_list[i]
                                #GEOcylinder_matrix2(self, obj, name, rotation_matrix, inner_radius, outer_radius, height, permittivity, conductivity)
                                obj = FDTDGeometryObjects_obj.GEOcylinder_matrix2(
                                    cyl_list[i], cylinder.name,
                                    rotation_matrix, cylinder.inner_radius,
                                    cylinder.outer_radius, cylinder.height,
                                    cylinder.permittivity,
                                    cylinder.conductivity)
                                #obj = FDTDGeometryObjects_obj.GEOcylinder_matrix(cylinder.name, rotation_matrix, cylinder.inner_radius, cylinder.outer_radius, cylinder.height, cylinder.permittivity, cylinder.conductivity)
                                #obj = FDTDGeometryObjects_obj.GEOcylinder_passedObj(cyl_list[i], cylinder.name, r.axis_point, r.axis_direction, r.angle_degrees, inner_radius, outer_radius, height, permittivity, conductivity)

                                blender_utilities.setActiveObject(
                                    obj, context=bpy.context)
                                blender_utilities.addToCollection(
                                    obj, group_name, removeFromOthers=False)
                                blender_utilities.addToCollection(
                                    obj, 'cylinders', removeFromOthers=False)

                                #angle_X = numpy.deg2rad(-90)
                                #angle_X = -0.5*numpy.pi
                                #angle_Y = 0
                                #angle_Z = 0
                                #FDTDGeometryObjects_obj.GEOcylinder(cylinder.name, cylinder.centro, cylinder.inner_radius, cylinder.outer_radius, cylinder.height, cylinder.permittivity, cylinder.conductivity, angle_X, angle_Y, angle_Z)

                                if self.GUI_loaded:
                                    bpy.context.window_manager.progress_update(
                                        i / N)
                                else:
                                    print('progress = {}'.format(i / N))

                            if self.GUI_loaded:
                                bpy.context.window_manager.progress_end()
                    ######################### if N > 0: end
        ##################################################################

        #########################
        # Not yet implemented:
        # Flag
        # structured_entries.flag;
        # Boundaries
        # structured_entries.boundaries;
        #########################

        # TODO: Save the layer settings somewhere for reuse
        #scene = Blender.Scene.GetCurrent()
        scene = bpy.context.scene

        layersOn = [
            layerManager.DefaultLayers.index('spheres') + 1,
            layerManager.DefaultLayers.index('blocks') + 1,
            layerManager.DefaultLayers.index('cylinders') + 1
        ]
        print(layersOn)
        #layersOn = [1,2,3]
        #print layersOn
        #Blender.Scene.GetCurrent().setLayers(layersOn)

        #scene.update(0);
        #Blender.Window.RedrawAll();
        #Blender.Window.WaitCursor(0);
        #Blender.Scene.GetCurrent().setLayers([1,3,4,5,6,7,8,9,10]);
        print('...done')
        #print Blender.Get('scriptsdir')
        #Blender.Run(Blender.Get('scriptsdir')+'/layer_manager.py')
        #layer_manager_objects = layer_manager.LayerManagerObjects()
        #Draw.Register(layer_manager_objects.gui, layer_manager_objects.event, layer_manager_objects.button_event)

        #print '=========================='
        #print Blender.Window.GetScreens()
        #print Blender.Window.GetAreaID()
        #print Blender.Window.GetAreaSize()
        #print Blender.Text.Get()
        #print '=========================='
        #~ Blender.Window.FileSelector(algosomething, "Import Bristol FDTD file...");
        #~ Blender.Run('~/.blender/scripts/bfdtd_import.py')

        print('Elapsed time: ', round(time.time() - start_time, 4), 'seconds')
예제 #9
0
    def execute(self):
        print("running read_meep...")
        filepath_basename = os.path.basename(self.filepath)
        (root, ext) = os.path.splitext(self.filepath)
        if ext == '.ctl':
            (MEEP_data_list,
             geo_list) = MEEP.MEEP_parser.getInfoFromCTL(self.filepath)
        else:
            with open(self.filepath) as infile:
                MEEP_data_list = MEEP.MEEP_parser.parse_MEEP(infile)
                geo_list = MEEP.MEEP_parser.parseGeometry(infile)

        for idx, MEEP_data_object in enumerate(MEEP_data_list):
            print('=== dataset {} ==='.format(idx))

            name = 'k-points-{}-{}'.format(filepath_basename, idx)

            # add lattice+reciprocal lattice basis vectors+cells
            (a0, a1, a2) = MEEP_data_object.getLatticeVectors()
            (b0, b1, b2) = MEEP_data_object.getReciprocalLatticeVectors()

            # add_lattice_objects(self, a0, a1, a2, b0, b1, b2, name = name+'-lattice_objects',
            # cone_length=self.cone_length,
            # cone_radius=self.cone_radius,
            # cylinder_radius=self.cylinder_radius)
            obj_lat_shifted_cell = add_lattice_cell(
                self,
                a0,
                a1,
                a2,
                name='lattice_cell-shifted',
                shift_origin=True,
                wiremode=True)

            # add k-point path and sphere following it
            L = MEEP_data_object.get_kpoints_in_cartesian_coordinates()
            if len(L) > 0:
                for i in L:
                    print(i)

                mesh = bpy.data.meshes.new(name)

                bm = bmesh.new()

                for v_co in L:
                    bm.verts.new(v_co)

                bm.verts.ensure_lookup_table()
                for i in range(len(L) - 1):
                    bm.edges.new([bm.verts[i], bm.verts[i + 1]])

                bm.to_mesh(mesh)
                mesh.update()

                object_data_add(self.context, mesh, operator=self.operator)
                bpy.ops.object.convert(target='CURVE')

                k_points_path_object = self.context.active_object
                k_points_path_object.name = name + '-path'

                print('Adding animation...')
                k_points_path_object.data.use_path = True
                scene = self.context.scene
                k_points_path_object.data.path_duration = scene.frame_end - scene.frame_start

                bpy.ops.mesh.primitive_uv_sphere_add()
                S = self.context.active_object
                S.name = name + '-sphere'
                L = numpy.power(MEEP_data_object.getReciprocalCellVolume(),
                                1 / 3)
                S.scale = 3 * [L / 20]

                # add a constraint to it
                constraint = S.constraints.new('FOLLOW_PATH')
                constraint.target = k_points_path_object

                #bpy.ops.object.constraint_add(type='FOLLOW_PATH')
                #C = S.constraints[-1]
                #C.target = k_points_path_object
                #selectObjects([S], active_object=S, context=self.context)
                #bpy.ops.constraint.followpath_path_animate(constraint="Follow Path", owner='OBJECT')

                override = {'constraint': constraint}
                bpy.ops.constraint.followpath_path_animate(
                    override, constraint='Follow Path')

                selectObjects([k_points_path_object],
                              active_object=k_points_path_object,
                              context=self.context)

            else:
                print('no k-points found')

        # we create an instance of the FDTDGeometryObjects class, which allows adding objects to the scene with shared materials (TODO: maybe find a better system?)
        FDTDGeometryObjects_obj = FDTDGeometryObjects.FDTDGeometryObjects()
        FDTDGeometryObjects_obj.addGeometryObjects(geo_list)

        print('FINISHED')
        return {'FINISHED'}