Exemple #1
0
def CheckPointConstraints(csg_file, pos_points, neg_points):
    # Save positive and negative points into temporary files.
    tmp_pos_file = os.path.join(csg_output_dir, '.pos.data')
    tmp_neg_file = os.path.join(csg_output_dir, '.neg.data')
    tmp_point_file = os.path.join(csg_output_dir, '.point.data')
    # Check positive points first.
    helper.SaveDataFile(tmp_point_file, pos_points)
    helper.Run('%s csg-flag -d %s -e %f -i %s -n %s -p %s' % \
               (os.environ['CSG_CPP_EXE'], tmp_point_file, 0, csg_file, \
                tmp_neg_file, tmp_pos_file))
    unsatisfied_pos = helper.LoadDataFile(tmp_neg_file)
    # Check if some points are missing.
    satisfied_pos = helper.LoadDataFile(tmp_pos_file)
    if satisfied_pos.shape[0] + unsatisfied_pos.shape[0] != pos_points.shape[0]:
        helper.PrintWithRedColor('Error: some pos constraints are ignored.')
    # Then check negative points.
    helper.SaveDataFile(tmp_point_file, neg_points)
    helper.Run('%s csg-flag -d %s -e %f -i %s -n %s -p %s' % \
               (os.environ['CSG_CPP_EXE'], tmp_point_file, 0, csg_file, \
                tmp_neg_file, tmp_pos_file))
    unsatisfied_neg = helper.LoadDataFile(tmp_pos_file)
    # Check if some points are missing.
    satisfied_neg = helper.LoadDataFile(tmp_neg_file)
    if satisfied_neg.shape[0] + unsatisfied_neg.shape[0] != neg_points.shape[0]:
        helper.PrintWithRedColor('Error: some neg constraints are ignored.')
    os.remove(tmp_pos_file)
    os.remove(tmp_neg_file)
    os.remove(tmp_point_file)
    return unsatisfied_pos, unsatisfied_neg
Exemple #2
0
def InstallEigen(root_folder, init=True):
  if init:
    helper.Run('wget http://bitbucket.org/eigen/eigen/get/3.3.4.zip')
    cpp_lib_folder = os.path.join(root_folder, 'cpp', 'lib')
    helper.Run('unzip 3.3.4.zip -d %s' % os.path.join(cpp_lib_folder))
    helper.Run('mv %s %s' % (os.path.join(cpp_lib_folder, \
     'eigen-eigen-5a0156e40feb'), os.path.join(cpp_lib_folder, 'eigen-3.3.4')))
    helper.Run('rm 3.3.4.zip')
    helper.PrintWithGreenColor('Installed Eigen')
Exemple #3
0
def InstallEigen(root_folder, init=True):
    if init:
        # helper.Run('wget http://bitbucket.org/eigen/eigen/get/3.3.4.zip')
        helper.Run(
            'wget https://github.com/eigenteam/eigen-git-mirror/archive/3.3.4.zip'
        )
        cpp_lib_folder = os.path.join(root_folder, 'cpp', 'lib')
        helper.Run('unzip 3.3.4.zip -d %s' % os.path.join(cpp_lib_folder))
        helper.Run('mv %s %s' % (os.path.join(cpp_lib_folder, \
         'eigen-git-mirror-3.3.4'), os.path.join(cpp_lib_folder, 'eigen-3.3.4')))
        helper.Run('rm 3.3.4.zip')
        helper.PrintWithGreenColor('Installed Eigen')
Exemple #4
0
def InstallJava():
    helper.Run('sudo apt-get install software-properties-common')
    helper.Run('sudo apt-get update')
    helper.Run('sudo apt install default-jdk')
    # Currently JAVA_HOME is hard coded.
    helper.RunWithStdout('ls /usr/lib/jvm/')
    if os.environ['TRAVIS_DIST_NAME'] == 'bionic':
        java_home = '/usr/lib/jvm/java-1.11.0-openjdk-amd64/'
    if os.environ['TRAVIS_DIST_NAME'] == 'xenial':
        java_home = '/usr/lib/jvm/java-1.8.0-openjdk-amd64/'
    if os.environ['TRAVIS_DIST_NAME'] == 'eoan':
        java_home = '/usr/lib/jvm/java-1.11.0-openjdk-amd64/'
    env_variables['JAVA_HOME'] = os.environ['JAVA_HOME'] = java_home
    path = os.path.join(java_home, 'bin') + ':' + os.environ['PATH']
    env_variables['PATH'] = os.environ['PATH'] = path
    helper.Run('%s -version' % os.path.join(java_home, 'bin', 'java'))
Exemple #5
0
def InstallMaven():
  # maven_url = 'http://mirrors.koehn.com/apache/maven/maven-3/3.5.3/' \
  #             'binaries/apache-maven-3.5.3-bin.zip'
  # maven_file = os.path.join(build_folder, 'maven.zip')
  # urllib.request.urlretrieve(maven_url, maven_file)
  # helper.Run('unzip -q %s -d %s' % (maven_file, build_folder))
  # os.remove(maven_file)
  # Add it to the environment variable.
  # for folder_name in os.listdir(build_folder):
  #   if 'maven' in folder_name:
  #     maven_loc = os.path.join(build_folder, folder_name, 'bin')
  #     env_variables['PATH'] = os.environ['PATH'] \
  #                           = maven_loc + ':' + os.environ['PATH']
  helper.Run('sudo apt-get install build-essential autoconf libtool flex bison mercurial maven')
  # Check maven.
  helper.Run('mvn -v')
def DetectPrimitivesInRoi(input_primitive_file, input_meta_point_file, \
  output_primitive_file, roi):
    # Call primitive-local.
    helper.Run('%s primitive-local -p %s -o %s -i %s -s %f %f %f %f %f %f' % (\
      os.environ['CSG_CPP_EXE'], input_primitive_file, output_primitive_file, \
      input_meta_point_file, roi[0], roi[1], roi[2], roi[3], roi[4], roi[5]))
    return ReadPrimitiveFile(output_primitive_file)
Exemple #7
0
def InstallJava():
  # java not hosted anymore: http://www.webupd8.org/2014/03/how-to-install-oracle-java-8-in-debian.html
  # helper.Run('sudo add-apt-repository -y ppa:webupd8team/java')
  # helper.Run('sudo apt-get update')
  # helper.Run('sudo apt-get install oracle-java8-installer')
  helper.Run('sudo apt-get install openjdk-8-jre')

  # Currently JAVA_HOME is hard coded.
  # java_home = '/usr/lib/jvm/java-8-oracle/' 
  # java_home = '/usr/lib/jvm/java-8-openjdk-amd64'
  java_path_cmd = "jrunscript -e \'java.lang.System.out.println(java.lang.System.getProperty(\"java.home\"));\'"
  java_home, _ = helper.Run(java_path_cmd, return_msg=True)
  env_variables['JAVA_HOME'] = os.environ['JAVA_HOME'] = java_home
  path = os.path.join(java_home, 'bin') + ':' + os.environ['PATH']
  env_variables['PATH'] = os.environ['PATH'] = path
  # helper.Run('%s -version' % os.path.join(java_home, 'bin', 'javac'))
  helper.Run('%s -version' % os.path.join(java_home, 'bin', 'java'))
Exemple #8
0
def InstallCGAL(build_folder, init=True):
  helper.Run('sudo apt-get install libcgal-dev')
  helper.PrintWithGreenColor('Installed libcgal-dev')
  if init:
    cgal_url = 'https://github.com/CGAL/cgal/releases/download/' \
               'releases%2FCGAL-4.12/CGAL-4.12.zip'
    cgal_file = os.path.join(build_folder, 'cgal.zip')
    urllib.request.urlretrieve(cgal_url, cgal_file)
    helper.Run('unzip -o -q %s -d %s' % (cgal_file, build_folder))
    os.remove(cgal_file)
  # Now you have the source code.
  helper.PrintWithGreenColor('Downloaded and unzipped CGAL 4.12')
  cgal_dir = ''
  for folder_name in os.listdir(build_folder):
    if 'cgal' in folder_name or 'CGAL' in folder_name:
      cgal_dir = os.path.join(build_folder, folder_name)
      break
  # Add cgal_root to the environment variable list.
  env_variables['CGAL_DIR'] = os.environ['CGAL_DIR'] = cgal_dir
def DetectPrimitives(mesh_file, output_primitive_file, output_meta_point_file, \
  options):
    # Given a mesh file, return a list of all primitives we detect and write them
    # into the output_primitive_file. The format of this file can be found in
    # cpp/src/common/file_helper.cpp:WritePrimFile. All primitives must be unique.
    # For comparison we can replace the code in this function with RANSAC,
    # GlobFit, etc. We always have to return an output_primitive_file and a meta
    # point file, but for debugging purposes, each method (RANSAC, GlobFit, etc.)
    # can pass options to ask for auxiliary files.
    # TODO: Since we are now using RANSAC, we assume it has the following optional
    # files:
    # ransac_config_file: will be removed in the future.
    # cluster_file: used to visualize the segmentation results.
    ransac_config_file = options['ransac_config_file']
    cluster_file = options['cluster_file']
    helper.Run('%s primitive -i %s -o %s -c %s -l %s -m %s -v' % ( \
      os.environ['CSG_CPP_EXE'], mesh_file, output_primitive_file, \
      ransac_config_file, cluster_file, output_meta_point_file))
    return ReadPrimitiveFile(output_primitive_file)
Exemple #10
0
def GetSketchCompile(sketch_harness_file):
    sketch_name = os.path.basename(sketch_harness_file)
    # Remove .sk extension.
    sketch_name = os.path.splitext(sketch_name)[0]
    sketch_exe = os.path.join(sketch_output_dir, sketch_name)
    sketch_cpp = os.path.join(sketch_output_dir, sketch_name + '.cpp')
    sketch_test_cpp = os.path.join(sketch_output_dir,
                                   sketch_name + '_test.cpp')
    # Compile.
    sketch_runtime_dir = os.path.join(os.environ['CSG_SKETCH_FRONTEND'], \
                                     'src/runtime/include')
    helper.Run('g++ -w -I %s -o %s %s %s' % \
      (sketch_runtime_dir, sketch_exe, sketch_cpp, sketch_test_cpp))
    # Execute and get the solution.
    solution = subprocess.check_output('%s -n 1' % sketch_exe, \
      stderr=subprocess.STDOUT, shell=True).decode('utf-8')
    lines = solution.splitlines()
    solution = []
    for l in lines:
        solution.append(l.strip())
        if '// End.' in l: break
    return '\n'.join(solution)
Exemple #11
0
    sys.exit(-1)

build_folder = os.path.realpath(sys.argv[1])
root_folder = os.path.dirname(os.path.realpath(sys.argv[0]))
if not os.path.exists(build_folder):
    os.makedirs(build_folder)
helper.PrintWithGreenColor('Build folder created.')

# Add a new environment variable to save the location of the root folder.
env_variables['CSG_ROOT'] = os.environ['CSG_ROOT'] = root_folder

# show LIBC version
helper.RunWithStdout('sudo dpkg -l libc6')

# This may work on Xenial
helper.Run('sudo apt-get update')
helper.Run('sudo apt-get install build-essential ' \
  'software-properties-common -y')
helper.RunWithStdout('sudo apt-get install gcc-snapshot -y')

# Install python dependencies.
helper.RunWithStdout(
    'sudo python3 -m pip install numpy scipy matplotlib ipython '
    'jupyter pandas sympy nose')
helper.RunWithStdout('sudo python3 -m pip install -U scikit-learn')
helper.RunWithStdout('sudo apt-get install autoconf libtool flex bison '
                     'mercurial zsh cmake -y')

# BISON version should be gt 3
helper.RunWithStdout('bison --version')
Exemple #12
0
def RunSketchPipeline():
    mesh_info = Preprocessing()
    all_pos_points = helper.LoadDataFile(mesh_info['pos_file'])
    vol_pos_points = helper.LoadDataFile(mesh_info['vol_pos_file'])
    all_neg_points = helper.LoadDataFile(mesh_info['neg_file'])
    satisfied_pos = np.zeros((0, 3))

    # Major loop starts here.
    part_file = os.path.join(point_output_dir, 'part_0.data')
    shutil.copy(mesh_info['vol_pos_file'], part_file)
    todo = [part_file]
    solutions = []
    while len(todo) > 0:
        # Pop the first element.
        part_file = todo[0]
        # Extract idx from the file name part_XX.data.
        idx = int(part_file[part_file.rfind('_') + 1:-len('.data')])
        volumes = helper.LoadDataFile(part_file)
        todo = todo[1:]
        print('Attempt to solve part %d...' % idx)

        # Compute the bounding box of volume. Intentionally enlarge it a bit.
        box_min = volumes.min(axis=0) - 0.01
        box_max = volumes.max(axis=0) + 0.01
        prim_roi = EnlargeBoundingBox((box_min[0], box_max[0], box_min[1], \
          box_max[1], box_min[2], box_max[2]), 1.1)

        # Merge volumes to get positive constraints.
        cpp_exe = os.environ['CSG_CPP_EXE']
        new_pos_file = os.path.join(point_output_dir, 'pos_%d.data' % idx)
        helper.Run('%s equiv-class -e %f -i %s -p %s -o %s' % (cpp_exe, eps, \
          part_file, mesh_info['primitive_file'], new_pos_file))

        # Subtract satisfied_pos from pos_idx.data.
        tmp_data_file = os.path.join(point_output_dir, '.tmp_%d.data' % idx)
        helper.SaveDataFile(tmp_data_file, satisfied_pos)
        helper.Run('%s remove-equiv-class -e %f -i %s -o %s -p %s -r %s' % (\
          cpp_exe, eps, new_pos_file, new_pos_file, \
          mesh_info['primitive_file'], tmp_data_file))
        os.remove(tmp_data_file)

        pos_points = helper.LoadDataFile(new_pos_file)
        if pos_points.size == 0:
            helper.PrintWithGreenColor('Part %d has been resolved.' % idx)
            continue
        solution, done = SolveOnePartWithOuterLoop(idx, pos_points, \
          all_neg_points, prim_roi, mesh_info)
        if done:
            helper.PrintWithGreenColor('Part %d is done.' % idx)
            # Generate current solution.
            solutions.append(solution)
            csg_file = os.path.join(csg_output_dir, 'solution_%d.scad' % idx)
            f = open(csg_file, 'w')
            # Enclose this solution with the bounding box.
            x_min, x_max, y_min, y_max, z_min, z_max = mesh_info[
                'bounding_box']
            f.write('intersection() {\n')
            f.write('translate([%f, %f, %f])\n' % (x_min, y_min, z_min))
            f.write('cube(size = [%f, %f, %f], center = false);\n' % \
              (x_max - x_min, y_max - y_min, z_max - z_min))
            f.write('union() {\n')
            for s in solutions:
                f.write(s)
                f.write('\n')
            f.write('}\n')
            f.write('}\n')
            f.close()
            # Check if all point constraints can be satisfied.
            tmp_pos_file = os.path.join(csg_output_dir, '.pos.data')
            tmp_neg_file = os.path.join(csg_output_dir, '.neg.data')
            helper.Run('%s csg-flag -d %s -e %f -i %s -n %s -p %s' % \
                       (cpp_exe, mesh_info['pos_file'], eps, csg_file, \
                        tmp_neg_file, tmp_pos_file))
            satisfied_pos = helper.LoadDataFile(tmp_pos_file)
            unsatisfied_pos = helper.LoadDataFile(tmp_neg_file)
            os.remove(tmp_pos_file)
            os.remove(tmp_neg_file)
            if unsatisfied_pos.size == 0:
                # We have found the solution.
                helper.PrintWithGreenColor('All constraints were satisfied. Result is ' \
                  'in %s.' % csg_file)
                return
        else:
            # Segment the volume.
            point_cloud_seg.SegmentPointCloud(part_file, seg_num, \
              part_file[:-len('.data')])
            # Get the last idx.
            last_part_file = todo[-1] if len(todo) > 0 else part_file
            last_idx = int(last_part_file[last_part_file.rfind('_') + 1 \
              : -len('.data')])
            new_idx = last_idx + 1
            for i in range(seg_num):
                new_part_file = \
                  part_file[:part_file.rfind('_') + 1] + str(new_idx + i) + '.data'
                shutil.copyfile(part_file[:-len('.data')] + '_' + str(i) + '.data' , \
                  new_part_file)
                todo.append(new_part_file)
Exemple #13
0
def SolveOnePart(idx, all_pos_constraints, all_neg_constraints, primitive_roi, \
  mesh_info):
    # Call this function to solve all_pos_constraints and all_neg_constraints
    # using primitives inside primitive_roi.
    # Returns a string that describes the csg tree, and done to indicate whether
    # the problem is solved.
    # Call Sketch to satisfy pos_constraints and neg_constraints.
    xmin, xmax, ymin, ymax, zmin, zmax = primitive_roi
    helper.PrintWithGreenColor('Part %d, roi (%f, %f, %f, %f, %f, %f)' \
      % (idx, xmin, xmax, ymin, ymax, zmin, zmax))
    print('Constraints: %d positive, %d negative.' % \
      (all_pos_constraints.shape[0], all_neg_constraints.shape[0]))
    # Save them for debugging purposes. They are duplicated in data.sk.
    pos_constraints_file = os.path.join(point_output_dir, 'pos_%d.data' % idx)
    helper.SaveDataFile(pos_constraints_file, all_pos_constraints)
    neg_constraints_file = os.path.join(point_output_dir, 'neg_%d.data' % idx)
    helper.SaveDataFile(neg_constraints_file, all_neg_constraints)

    # Prepare the data file.
    sketch_data_file = os.path.join(sketch_harness_dir, 'data_%d.sk' % idx)
    sketch_idx_file = os.path.join(sketch_harness_dir, 'idx_%d.sk' % idx)
    helper.SavePointToSketch(sketch_data_file, sketch_idx_file, \
      all_pos_constraints, all_neg_constraints)

    # Prepare the primitive file.
    prim_file = os.path.join(point_output_dir,
                             'surface_primitives_%d.prim' % idx)
    unsat_code = 1

    def UnsatHandler(command, exit_code):
        if exit_code != unsat_code:
            helper.DefaultExceptionHandle(command, exit_code)
        else:
            helper.PrintWithGreenColor('UNSAT detected.')

    while True:
        xmin, xmax, ymin, ymax, zmin, zmax = primitive_roi
        helper.Run('%s primitive-local -p %s -o %s -i %s -s %f %f %f %f %f %f' % ( \
          os.environ['CSG_CPP_EXE'], mesh_info['primitive_file'], prim_file, \
          '.dummy.meta', xmin, xmax, ymin, ymax, zmin, zmax))
        # See if the problem is SAT.
        code = helper.Run('%s remove-prim -e %f -i %s -o %s -n %s -p %s -v' % ( \
          os.environ['CSG_CPP_EXE'], eps, prim_file, prim_file, \
          neg_constraints_file, pos_constraints_file), UnsatHandler)
        if code == 0:
            break
        elif code == unsat_code:
            # Try to enlarge the roi.
            if Enclose(primitive_roi, mesh_info['bounding_box']):
                helper.PrintWithRedColor('Roi is already larger than the bounding ' \
                  'box but the problem is still UNSAT. Should never happen.')
                sys.exit(-1)
            helper.PrintWithGreenColor(
                'Enlarge the primitive roi and retry...')
            primitive_roi = EnlargeBoundingBox(primitive_roi, 1.1)
        else:
            # Should never happen.
            helper.PrintWithRedColor('See exit code other than 1. ' \
              'Should never happen.')
            sys.exit(-1)

    # Now the surface primitives are stored in prim_file and all of them are
    # necessary. We can count the number of solid primitives and terminate it
    # early if we are sure the solution is too big for sketch to solve.
    estimated_prim_num = \
      surface_primitive_to_sketch.CountMinimumNumberOfSolidPrimitives(prim_file)
    if estimated_prim_num > max_prim_num:
        # Call segmentation.
        helper.PrintWithRedColor('Problem seems to require a deeper CSG tree. ' \
                                 'Call segmentation.')
        return '', False

    prim_sketch_file = os.path.join(sketch_harness_dir, \
      'primitives_%d.sk' % idx)
    surface_primitive_to_sketch.WriteSurfacePrimitivesToSolidSketch( \
      prim_file, prim_sketch_file, mesh_info['max_offsets'] + 10 * eps)
    sketch_harness_file_name = '%s_%d' % (output_dir.split('/')[-1], idx)
    sketch_harness_file = os.path.join(sketch_harness_dir, \
      sketch_harness_file_name) + '.sk'
    sketch_solver_file = os.path.join(sketch_harness_dir, \
      'csg_solver_%d.sk' % idx)
    # Sketch harness file.
    CreateSketch(sketch_harness_file, sketch_solver_file, \
      os.path.basename(sketch_data_file), sketch_idx_file, \
      os.path.basename(prim_sketch_file))
    # Run Sketch and get its log.
    sketch_output_file = os.path.join(sketch_output_dir, \
      sketch_harness_file_name + '.log')
    sketch_done = GetSketch(sketch_harness_file, sketch_output_file, \
      timeout)
    # Check if it succeeded.
    if not sketch_done or '[SKETCH] DONE' not in open(
            sketch_output_file).read():
        helper.PrintWithRedColor('Problem is too hard. Need segmentation.')
        return '', False
    helper.PrintWithGreenColor('Sketch succeeded.')
    # Display the solution.
    sketch_solution = GetSketchCompile(sketch_harness_file)
    # Save the results into a scad file.
    csg_file = os.path.join(csg_output_dir, 'csg_%d.scad' % idx)
    f = open(csg_file, 'w')
    f.write(sketch_solution)
    f.close()
    # As a sanity check.
    unsatisfied_pos, unsatisfied_neg = CheckPointConstraints(csg_file, \
      all_pos_constraints, all_neg_constraints)
    if unsatisfied_pos.size + unsatisfied_neg.size > 0:
        helper.PrintWithRedColor('Still see unsatisfied constraints. ' \
          'Should never happen.')
        sys.exit(-1)
    # Done.
    return sketch_solution, True
Exemple #14
0
def Preprocessing():
    mesh_info = {}
    # Bounding box of the mesh.
    mesh_bounding_box = helper.GetOffMeshBoundingBox(mesh_file_loc)
    print('Bounding box of the mesh: ' + str(mesh_bounding_box))
    # Enlarge the bounding box a bit.
    box_min = np.array(mesh_bounding_box[::2])
    box_max = np.array(mesh_bounding_box[1::2])
    box_diag = box_max - box_min
    box_min -= box_diag * 0.1
    box_max += box_diag * 0.1
    enlarged_bounding_box = (box_min[0], box_max[0], box_min[1], box_max[1], \
                             box_min[2], box_max[2])
    mesh_info['bounding_box'] = enlarged_bounding_box
    mesh_info['max_offsets'] = max([abs(x)
                                    for x in enlarged_bounding_box]) * 3.0

    # Compute the level-set.
    cpp_exe = os.environ['CSG_CPP_EXE']
    level_set_file = os.path.join(point_output_dir, 'levelset.ls')
    print('Computing the level set...')
    # Enlarge eps a bit to avoid numerical issues.
    bigger_eps = eps * 1.1
    helper.Run('%s level-set -i %s -d %f -o %s' % (cpp_exe, mesh_file_loc, \
                                                   bigger_eps, level_set_file))
    mesh_info['level_set_file'] = level_set_file

    # Get surface primitives.
    # init_prim_file includes all detected primitives and auxiliary planes.
    init_prim_file = os.path.join(point_output_dir, 'init_primitives.prim')
    # cluster_file and ransac_config_file are used by RANSAC.
    cluster_file = os.path.join(point_output_dir, 'primitives.clu')
    ransac_config_file = os.path.join(os.path.dirname( \
      os.path.realpath(mesh_file_loc)), 'ransac.conf')
    dummy_meta_file = os.path.join(point_output_dir, '.tmp.meta')
    print('Getting all primitives...')
    helper.Run('%s primitive -i %s -o %s -c %s -l %s -m %s -v' % (cpp_exe, \
      mesh_file_loc, init_prim_file, ransac_config_file, cluster_file, \
      dummy_meta_file))
    # Get auxiliary primitives.
    aux_prim_file = os.path.join(point_output_dir, 'aux_primitives.prim')
    init_and_aux_prim_file = os.path.join(point_output_dir, \
      'init_and_aux_primitives.prim')
    surface_primitive_to_sketch.AddAuxiliaryPrimitives( \
      init_prim_file, aux_prim_file, init_and_aux_prim_file)
    os.remove(dummy_meta_file)

    # Sample points.
    surface_sample_file = os.path.join(point_output_dir, 'surface_sample.data')
    print('Surface sampling...')
    helper.Run('%s surface-sample -b %f -d %f -e %f -i %s -l %s -o %s -p %s -v' \
               % (cpp_exe, 10 * bigger_eps, surface_density, bigger_eps, \
                  mesh_file_loc, level_set_file, surface_sample_file, \
                  init_and_aux_prim_file))
    init_vol_pos_file = os.path.join(point_output_dir, 'init_vol_pos.data')
    init_vol_neg_file = os.path.join(point_output_dir, 'init_vol_neg.data')
    print('Volume sampling...')
    helper.Run('%s volume-sample -d %f -e %f -i %s -l %s -n %s -p %s -r %s -v' % \
               (cpp_exe, volume_density, bigger_eps, mesh_file_loc, \
                level_set_file, init_vol_neg_file, init_vol_pos_file, \
                init_and_aux_prim_file))
    surface_sample = helper.LoadDataFile(surface_sample_file)
    pos_sample = helper.LoadDataFile(init_vol_pos_file)
    neg_sample = helper.LoadDataFile(init_vol_neg_file)
    all_samples = np.vstack((surface_sample, pos_sample, neg_sample))
    tmp_sample_file = os.path.join(point_output_dir, '.tmp.data')
    helper.SaveDataFile(tmp_sample_file, all_samples)
    equiv_pos_file = os.path.join(point_output_dir, 'equiv_pos.data')
    equiv_neg_file = os.path.join(point_output_dir, 'equiv_neg.data')
    all_pos_file = os.path.join(point_output_dir, 'all_pos.data')
    all_neg_file = os.path.join(point_output_dir, 'all_neg.data')
    print('Calling equiv-class-flag...')
    helper.Run('%s equiv-class-flag -d %f -e %s -i %s -l %s -m %s -n %s -o %s ' \
               '-p %s -q %s -v' % (cpp_exe, bigger_eps, equiv_pos_file, \
               tmp_sample_file, level_set_file, mesh_file_loc, all_neg_file, \
               all_pos_file, init_and_aux_prim_file, equiv_neg_file))
    os.remove(tmp_sample_file)

    # The problem is resolved as long as all points in equiv_pos_file and
    # equiv_neg_file are satisifed using detected primitives.
    mesh_info['pos_file'] = equiv_pos_file
    mesh_info['neg_file'] = equiv_neg_file
    # Now we can filter redundant primitives.
    final_prim_file = os.path.join(point_output_dir, 'final_primitives.prim')
    helper.Run('%s add-separator -a %s -e %f -i %s -o %s -n %s -p %s -v' % \
      (cpp_exe, aux_prim_file, eps, init_prim_file, final_prim_file, \
       equiv_neg_file, equiv_pos_file))
    # Do it one more time.
    helper.Run('%s remove-prim -e %f -i %s -o %s -n %s -p %s -v' % (cpp_exe, \
      eps, final_prim_file, final_prim_file, equiv_neg_file, equiv_pos_file))
    # Add a giant bounding sphere to allow for negation.
    surface_primitive_to_sketch.AddBoundingSphere(final_prim_file, \
      final_prim_file, mesh_info['max_offsets'] + 10 * eps)
    helper.Run('%s equiv-class -e %f -i %s -p %s -o %s -v' % (cpp_exe, eps, \
      equiv_pos_file, final_prim_file, equiv_pos_file))
    helper.Run('%s equiv-class -e %f -i %s -p %s -o %s -v' % (cpp_exe, eps, \
      equiv_neg_file, final_prim_file, equiv_neg_file))
    mesh_info['primitive_file'] = final_prim_file

    # Clean up volumetric samples.
    print('Filtering volumetric samples (%d positive, %d negative before).' % \
      (pos_sample.shape[0], neg_sample.shape[0]))
    final_vol_pos_file = os.path.join(point_output_dir, 'final_vol_pos.data')
    final_vol_neg_file = os.path.join(point_output_dir, 'final_vol_neg.data')
    helper.IntersectPointSetFiles(all_neg_file, init_vol_neg_file, \
      final_vol_neg_file)
    helper.IntersectPointSetFiles(all_pos_file, init_vol_pos_file, \
      final_vol_pos_file)
    print('Filtering volumtric samples (%d positive, %d negative after).' % \
      (helper.LoadDataFile(final_vol_pos_file).shape[0], \
       helper.LoadDataFile(final_vol_neg_file).shape[0]))
    final_vol_pos_points = helper.LoadDataFile(final_vol_pos_file)
    equiv_pos_points = helper.LoadDataFile(equiv_pos_file)
    diff_points = helper.SubtractPointSets(equiv_pos_points,
                                           final_vol_pos_points)
    if diff_points.size > 0:
        final_vol_pos_points = np.vstack((final_vol_pos_points, diff_points))
    helper.SaveDataFile(final_vol_pos_file, final_vol_pos_points)
    mesh_info['vol_pos_file'] = final_vol_pos_file
    mesh_info['vol_neg_file'] = final_vol_neg_file
    print('Preprocessing done.')
    return mesh_info
Exemple #15
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--build_dir', default='', help='build directory path.')
    parser.add_argument('-dp', '--deps', action='store_false', help='Disable apt-get & py3 dependencies.')
    parser.add_argument('-eg', '--eigen', action='store_false', help='Disable Eigen install.') 
    parser.add_argument('-cg', '--cgal', action='store_false', help='Disable CGAL install.')
    parser.add_argument('-c', '--cpp', action='store_false', help='Disable source cpp compilation.')
    parser.add_argument('-sk', '--sketch', action='store_false', help='Disable sketch installation.')
    args = parser.parse_args()
    print('Arguments:', args)

    # Usage: python3 install.py -d <build folder>
    if not args.build_dir:
      print('Usage: python3 install.py -d <build_folder>')
      sys.exit(-1)

    build_folder = os.path.realpath(args.build_dir)
    root_folder = HERE
    if not os.path.exists(build_folder):
      os.makedirs(build_folder)
    helper.PrintWithGreenColor('Build folder created :{}'.format(build_folder))
    
    # Add a new environment variable to save the location of the root folder.
    env_variables['CSG_ROOT'] = os.environ['CSG_ROOT'] = root_folder
    
    # Check all C++ dependencies.
    if args.deps:
      print('Attempt to install build-essential, autoconf, libtool, flex, bison, '
            'mecurial, zsh, and cmake. Asking for sudo privilege.')
      # This works for Ubuntu 17.04 and 16.04.
      exit_code = helper.Run('sudo apt-get install gcc-6 g++-6 -y', None)
      if exit_code != 0:
        # This works for Ubuntu 14.04.
        helper.Run('sudo apt-get update')
        helper.Run('sudo apt-get install build-essential ' \
          'software-properties-common -y')
        helper.Run('sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y')
        helper.Run('sudo apt-get update')
        helper.Run('sudo apt-get install gcc-snapshot -y')
        helper.Run('sudo apt-get update')
        helper.Run('sudo apt-get install gcc-6 g++-6 -y')
        helper.Run('sudo apt-get install autoconf libtool flex bison '
          'mercurial zsh cmake')
    
      # Install python dependencies.
      helper.Run('python3 -m pip install -U pip setuptools')
      helper.Run('python3 -m pip install --upgrade pip')
      helper.Run('python3 -m pip install numpy scipy matplotlib ipython '
                 'jupyter pandas sympy nose')
      helper.Run('python3 -m pip install -U scikit-learn')
    
    # Install CGAL.
    InstallCGAL(build_folder, args.eigen)
    
    # Install Eigen-3.3.4.
    InstallEigen(root_folder, args.cgal)
    
    # Compile cpp.
    if args.cpp:
      cpp_build_folder = os.path.join(build_folder, 'cpp')
      if not os.path.exists(cpp_build_folder):
        os.makedirs(cpp_build_folder)
      os.chdir(cpp_build_folder)
      os.environ['CC'] = '/usr/bin/gcc-6'
      os.environ['CXX'] = '/usr/bin/g++-6'
      helper.Run('cmake -DCGAL_DIR=%s %s' % (env_variables['CGAL_DIR'], \
                                             os.path.join(root_folder, 'cpp')))
      helper.Run('make')
      helper.PrintWithGreenColor('C++ program compiled successfully.')
      env_variables['CSG_CPP_EXE'] = os.path.join(cpp_build_folder,
                                                  'csg_cpp_command')
    
    # Install Sketch.
    # Try calling Sketch. If it is successful, we are done.
    if CheckSketch(build_folder):
      SaveCustomizedEnvironmentVariables(env_variables, os.path.join(
        build_folder, 'ENVIRONMENT'))
      helper.PrintWithGreenColor('Installation Done.')
      sys.exit(0)
    
    # If we are here, Sketch is not properly installed.
    # First, install Oracle JDK 8.
    print('Attempt to install Oracle JDK 8. Asking for sudo privilege.')
    InstallJava()
    
    # Next, install maven.
    InstallMaven()
    
    # Download sketch-backend.
    sketch_folder = os.path.join(build_folder, 'sketch')
    if not os.path.exists(sketch_folder):
      os.makedirs(sketch_folder)
    if args.sketch:
      # Sketch-backend.
      os.chdir(sketch_folder)
      helper.Run('hg clone https://bitbucket.org/gatoatigrado/sketch-backend')
      helper.Run('mv sketch-backend sketch-backend-default')
      # Use this version of sketch.
      helper.Run('hg clone -r 04b3403 sketch-backend-default sketch-backend')

    sketch_backend_folder = os.path.join(sketch_folder, 'sketch-backend')
    env_variables['CSG_SKETCH_BACKEND'] = sketch_backend_folder

    if args.sketch:
      os.chdir(sketch_backend_folder)
      helper.Run('bash autogen.sh')
      helper.Run('./configure')
      helper.Run('make -j2')
      # Interestingly, I need to manually do the following copy and paste work to
      # avoid an error in sketch-frontend.
      sketch_solver_folder = os.path.join(sketch_backend_folder, 'src/SketchSolver')
      shutil.copyfile(os.path.join(sketch_solver_folder, 'libcegis.a'), \
                      os.path.join(sketch_solver_folder, '.libs/libcegis.a'))
      shutil.copyfile(os.path.join(sketch_solver_folder, 'cegis'), \
                      os.path.join(sketch_solver_folder, '.libs/cegis'))
    
    # Download sketch-frontend.
    os.chdir(sketch_folder)
    if args.sketch:
      helper.Run('hg clone https://bitbucket.org/gatoatigrado/sketch-frontend')
      helper.Run('mv sketch-frontend sketch-frontend-default')
      # Use this version of sketch.
      helper.Run('hg clone -r 42c057c sketch-frontend-default sketch-frontend')
    sketch_frontend_folder = os.path.join(sketch_folder, 'sketch-frontend')
    env_variables['CSG_SKETCH_FRONTEND'] = sketch_frontend_folder
    os.chdir(sketch_frontend_folder)
    if args.sketch:
      helper.Run('make system-install DESTDIR=/usr/bin SUDOINSTALL=1')
    
    # Now check Sketch again.
    if not CheckSketch(build_folder):
      helper.PrintWithRedColor('Failed to install Sketch. Please fix.')
      sys.exit(-1)
    
    SaveCustomizedEnvironmentVariables(env_variables, os.path.join(
      build_folder, 'ENVIRONMENT'))
    helper.PrintWithGreenColor('Installation Done.')