示例#1
0
	def select_marked_region(self, attr = "unused"):
		select = []
		if len(self.marked) != 1:
			raise Beep("Must be exactly one marked node!")
		if len(self.current_nodes) != 1:
			raise Beep("Must be exactly one selected node!")
		import Path
		a = Path.path_to(self.get_current())
		b = Path.path_to(self.marked.keys()[0])

		while a and b and a[0] == b[0]:
			del a[0]
			del b[0]

		if a and b:
			select = []
			s = 0
			a = a[0]
			b = b[0]
			for x in a.parentNode.childNodes:
				if x == a:
					s = not s
				elif x == b:
					s = not s
				if s:
					select.append(x)
			self.move_to(select)
		else:
			raise Beep("One node is a parent of the other!")
示例#2
0
def dict2dir(dir, dic, mode="w"):
    dir = Path(dir)
    if not dir.exists():
        dir.mkdir()
    for filename, content in dic.items():
        p = Path(dir, filename)
        if isinstance(content, dict):
            dict2dir(p, content)
            continue
        f = open(p, mode)
        f.write(content)
        f.close()
示例#3
0
    def lbl_path_clicked(self, lbl):
        btns = (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
        dialog = Gtk.FileChooserDialog("Choose a folder", self.win_main, Gtk.FileChooserAction.SELECT_FOLDER, btns)
        startingPath = Path.full(self.prefs.get("last-opened-folder"))
        dialog.set_current_folder(startingPath)
        response = dialog.run()

        if response == Gtk.ResponseType.OK:
            pathStr = dialog.get_filename()
            self.prefs.set("last-opened-folder", pathStr)
            self.cbox_path.get_child().set_text(Path.pretty(pathStr))

        dialog.destroy()
        return True
示例#4
0
def rf2():
    """
    Submission: rf2_0704_04.csv
    3000 trees
    E_val: 0.871431
    E_in: 0.999998
    E_out:
    30000 trees
    E_val:
    E_in:
    E_out:
    """
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.ensemble import RandomForestClassifier

    X, y = dataset.load_train()

    raw_scaler = StandardScaler()
    raw_scaler.fit(X)
    X_scaled = raw_scaler.transform(X)

    rf = RandomForestClassifier(n_estimators=30000, oob_score=True, n_jobs=-1,
                                class_weight='auto', max_features='log2')
    rf.fit(X_scaled, y)

    logger.debug('Eval(oob): %f', rf.oob_score_)
    logger.debug('Ein: %f', Util.auc_score(rf, X_scaled, y))

    IO.cache(rf, Path.of_cache('rf.RandomForestClassifier.log2.pkl'))
    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('rf', rf)]), 'rf2_0704_04')
示例#5
0
    def btn_search_clicked(self, data):
        tab = self.getActiveTab()
        if tab.isSearching:
            self.app.mbox.error("There is already a search happening in this tab.")
            return

        self.clear_results()
        string = self.cbox_search.get_active_text()
        path = Path.pretty(self.cbox_path.get_active_text())
        self.cbox_path.get_child().set_text(path)

        if not string.strip():
            tab.getTextBuffer().set_text("You forgot to provide a search string")
            self.cbox_search.get_child().grab_focus()
            return True
        if not path.strip():
            tab.getTextBuffer().set_text("You forgot to provide a search folder")
            self.cbox_path.get_child().grab_focus()
            return True

        self.add_path_history(path)
        self.add_search_history(string)

        # Pass parameters to tab's grep engine
        tab.ge.exclude_dirs = self.prefs.get("exclude-dirs")
        tab.ge.exclude_files = self.prefs.get("exclude-files")
        tab.ge.max_matches = self.app.prefs.get("match-limit")
        tab.ge.case_sensitive = self.chk_case.get_active()

        # Update Tab label widgets
        tab.setTitleText(string + " : " + path)
        tab.setSpinner(True)

        tab.startSearch(string, path, self.set_result_status)
示例#6
0
def svc():
    """
    Submission: svc_0703_04.csv
    E_val:
    E_in:
    E_out:
    """
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.svm import SVC
    from sklearn.cross_validation import StratifiedKFold
    from sklearn.grid_search import RandomizedSearchCV
    from sklearn.calibration import CalibratedClassifierCV
    from scipy.stats import expon

    X, y = dataset.load_train()

    raw_scaler = StandardScaler()
    raw_scaler.fit(X)
    X_scaled = raw_scaler.transform(X)

    svc = SVC(kernel='linear', class_weight='auto')
    rs = RandomizedSearchCV(svc, n_iter=50, scoring='roc_auc', n_jobs=-1,
                            cv=StratifiedKFold(y, 5),
                            param_distributions={'C': expon()})
    rs.fit(X_scaled, y)

    logger.debug('Got best SVC.')
    logger.debug('Grid scores: %s', rs.grid_scores_)
    logger.debug('Best score (E_val): %s', rs.best_score_)
    logger.debug('Best params: %s', rs.best_params_)
    IO.cache(rs, Path.of_cache('svc.RandomizedSearchCV.SVC.pkl'))

    svc = rs.best_estimator_
    IO.cache(rs, Path.of_cache('svc.SVC.pkl'))

    isotonic = CalibratedClassifierCV(svc, cv=StratifiedKFold(y, 5),
                                      method='isotonic')
    isotonic.fit(X_scaled, y)
    IO.cache(rs, Path.of_cache('svc.CalibratedClassifierCV.isotonic.pkl'))

    logger.debug('Got best isotonic CalibratedClassifier.')
    logger.debug('E_in (isotonic): %f', Util.auc_score(isotonic, X_scaled, y))

    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('svc', isotonic)]), 'svc_0703_04')
示例#7
0
    def activate(self, searchPath=None):
        self.reload_search_box()
        self.reload_path_box()
        if searchPath:
            self.cbox_path.get_child().set_text(Path.pretty(searchPath))

        self.chk_case.set_active(self.prefs.get("case-sensitive"))
        self.cbox_search.get_child().grab_focus()
        self.gtk_window.show_all()
示例#8
0
def execute(helix, argv):
    path = ""
    inp = " "
    utili={"Author","About"}
    utile={"Modules","Base","Lib","AppData","Manp"}
    while inp != "":
        inp = input("Insert the path of the file: ")
        if inp == "":
            break
        elif os.path.isfile(inp):
            path += inp + ","
        else:
                perror("File " + inp + " not found.")
    names = extractFileName(path)
    f = open(Path.path_tinst() + "manifest.ifest", "w")
    f.write("Name:" + names.replace(".py", "").lower() + "\n")
    temp = ""
    while not 0 < len(temp)<=32 :
        temp = input("Write you sign key: ")
    f.write("Signed:" + temp + "\n")
    for temp in utili:
        inp=input(temp+": ")
        if inp != "":
            f.write(temp+": "+inp+"\n")
    temp = ""
    while temp == "":
        temp = input("Write the tag of the module: ")
    f.write("Tag:" + temp.replace(" ", "") + "\n")
    for temp in utile:
        inp=" "
        while inp != "":
            inp=input("What do you want to put in "+temp+"? (Separate them with \",\"): ").replace(" ","")
            if inp!="" and names.__contains__(inp):
                f.write(temp+":" + inp + "\n")
                names.replace(inp+",","")
                break
    f.close()
    zipf = zipfile.ZipFile(Path.path_tinst() + "package.zip", "w")
    for fila in path.split(",")[:-1]:
        zipf.write(fila, fila.split(os.sep)[-1])
    zipf.write(Path.path_tinst() + "manifest.ifest", "manifest.ifest")
    zipf.close()
    os.remove(Path.path_tinst() + "manifest.ifest")
    psuccess("File ready at: " + Path.path_tinst())
示例#9
0
    def _buildPathArea(self, obj, baseobject, isHole, start, getsim):
        '''_buildPathArea(obj, baseobject, isHole, start, getsim) ... internal function.'''
        PathLog.track()
        area = Path.Area()
        area.setPlane(PathUtils.makeWorkplane(baseobject))
        area.add(baseobject)

        areaParams = self.areaOpAreaParams(obj, isHole)

        heights = [i for i in self.depthparams]
        PathLog.debug('depths: {}'.format(heights))
        area.setParams(**areaParams)
        obj.AreaParams = str(area.getParams())

        PathLog.debug("Area with params: {}".format(area.getParams()))

        sections = area.makeSections(mode=0, project=self.areaOpUseProjection(obj), heights=heights)
        PathLog.debug("sections = %s" % sections)
        shapelist = [sec.getShape() for sec in sections]
        PathLog.debug("shapelist = %s" % shapelist)

        pathParams = self.areaOpPathParams(obj, isHole)
        pathParams['shapes'] = shapelist
        pathParams['feedrate'] = self.horizFeed
        pathParams['feedrate_v'] = self.vertFeed
        pathParams['verbose'] = True
        pathParams['resume_height'] = obj.SafeHeight.Value
        pathParams['retraction'] = obj.ClearanceHeight.Value
        pathParams['return_end'] = True
        # Note that emitting preambles between moves breaks some dressups and prevents path optimization on some controllers
        pathParams['preamble'] = False

        if not self.areaOpRetractTool(obj):
            pathParams['threshold'] = 2.001 * self.radius

        if self.endVector is not None:
            pathParams['start'] = self.endVector
        elif PathOp.FeatureStartPoint & self.opFeatures(obj) and obj.UseStartPoint:
            pathParams['start'] = obj.StartPoint

        obj.PathParams = str({key: value for key, value in pathParams.items() if key != 'shapes'})
        PathLog.debug("Path with params: {}".format(obj.PathParams))

        (pp, end_vector) = Path.fromShapes(**pathParams)
        PathLog.debug('pp: {}, end vector: {}'.format(pp, end_vector))
        self.endVector = end_vector

        simobj = None
        if getsim:
            areaParams['Thicken'] = True
            areaParams['ToolRadius'] = self.radius - self.radius * .005
            area.setParams(**areaParams)
            sec = area.makeSections(mode=0, project=False, heights=heights)[-1].getShape()
            simobj = sec.extrude(FreeCAD.Vector(0, 0, baseobject.BoundBox.ZMax))

        return pp, simobj
示例#10
0
def rf():
    """
    Submission: rf_0708_01.csv
    3000 trees
    E_val: 0.871837
    E_in: 0.999998
    E_out: 0.882316801296279
    15000 trees
    E_val: 0.872011
    E_in: 0.999998
    E_out: 0.8824869811781106
    30000 trees
    E_val: 0.871928
    E_in:
    E_out:

    depth=4; 12000 trees
    E_val: 0.969158
    E_in:
    E_out:
    """
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.ensemble import RandomForestClassifier
    import numpy as np

    X, y = dataset.load_train(depth=1)

    raw_scaler = StandardScaler()
    raw_scaler.fit(np.r_[X, dataset.load_test()])
    X_scaled = raw_scaler.transform(X)
    del X
    import gc
    gc.collect()

    rf = RandomForestClassifier(n_estimators=12000, oob_score=True, n_jobs=-1,
                                class_weight='auto')
    rf.fit(X_scaled, y)

    logger.debug('RandomForestClassifier fitted')

    logger.debug('E_val(oob): %f', rf.oob_score_)
    logger.debug('E_in(full): %f', Util.auc_score(rf, X_scaled, y))

    X, y = dataset.load_train()
    X_scaled = raw_scaler.transform(X)
    logger.debug('E_in (depth=0): %f', Util.auc_score(rf, X_scaled, y))
    del X
    gc.collect()

    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('rf', rf)]), 'rf_0708_01')

    logger.debug('caching fitted RandomForestClassifier')
    IO.cache(rf, Path.of_cache('rf.RandomForestClassifier.12000.pkl'))
    logger.debug('cached fitted RandomForestClassifier')
示例#11
0
 def __init__(self, reponame, append=True):
     self.reponame = reponame
     self.path = Path.path_evlog() + reponame
     self.io = None
     if append:
         self.io = open(self.path, "a")
     else:
         self.io = open(self.path, "w")
     self.io.write("[%s] %s:\n\n" % (EventCollector.__get_time(), reponame))
     self.io.flush()
示例#12
0
        def cached_func(*args, **kwargs):
            pkl_path = Path.of_cache(file_path + '.pkl')
            data = fetch_cache(pkl_path)

            if data is None:
                data = func(*args, **kwargs)

                cache(data, pkl_path)

            return data
示例#13
0
def lr_with_fs():
    """
    Submission: lr_with_fs_0703_01.csv
    E_val:
    E_in:
    E_out:
    """
    from sklearn.linear_model import LogisticRegressionCV, LogisticRegression
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.cross_validation import StratifiedKFold
    from sklearn.feature_selection import RFECV
    import pylab as pl

    X, y = dataset.load_train()

    raw_scaler = StandardScaler()
    raw_scaler.fit(X)
    X_scaled = raw_scaler.transform(X)

    pkl_path = Path.of_cache('lr_with_fs.RFECV.pkl')
    rfe = IO.fetch_cache(pkl_path)
    if rfe is None:
        rfe = RFECV(estimator=LogisticRegression(class_weight='auto'),
                    cv=StratifiedKFold(y, 5), scoring='roc_auc')
        rfe.fit(X_scaled, y)
        IO.cache(rfe, pkl_path)

        print("Optimal number of features : %d" % rfe.n_features_)

        # Plot number of features VS. cross-validation scores
        pl.figure()
        pl.xlabel("Number of features selected")
        pl.ylabel("Cross validation score (AUC)")
        pl.plot(range(1, len(rfe.grid_scores_) + 1), rfe.grid_scores_)
        pl.savefig('lr_with_fs.refcv')

    X_pruned = rfe.transform(X_scaled)

    new_scaler = StandardScaler()
    new_scaler.fit(X_pruned)
    X_new = new_scaler.transform(X_pruned)

    clf = LogisticRegressionCV(cv=10, scoring='roc_auc', n_jobs=-1)
    clf.fit(X_new, y)

    print('CV scores: %s' % clf.scores_)
    print('Ein: %f' % Util.auc_score(clf, X_new, y))

    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('rfe', rfe),
                                 ('scale_new', new_scaler),
                                 ('lr', clf)]), 'lr_with_fs_0703_01')
示例#14
0
def gbdt_search():
    """
    Grid search for best n_estimators.
    Best params: {'loss': 'deviance', 'n_estimators': 100}
    Submission: gbdt_search_0707_01.csv
    E_val: 0.883786743214
    E_in: 0.887785
    E_out: 0.8848760405053878
    """
    from sklearn.ensemble import GradientBoostingClassifier
    from sklearn.preprocessing import StandardScaler
    from sklearn.grid_search import GridSearchCV
    from sklearn.cross_validation import StratifiedKFold
    from sklearn.pipeline import Pipeline
    import numpy as np

    X, y = dataset.load_train()
    raw_scaler = StandardScaler()
    X_scaled = raw_scaler.fit_transform(X)

    param_grid = {
        'loss': ['deviance', 'exponential'],
        'n_estimators': np.arange(100, 1001, 100)
    }

    params = {'learning_rate': 0.1, 'subsample': 0.5}

    gb = GradientBoostingClassifier(**params)
    grid = GridSearchCV(gb, param_grid, scoring='roc_auc', n_jobs=-1,
                        cv=StratifiedKFold(y, 5), refit=True, verbose=1)
    grid.fit(X_scaled, y)

    logger.debug('Got best GBDT.')
    logger.debug('Grid scores: ')
    for i, grid_score in enumerate(grid.grid_scores_):
        print('\t%d00: %s' % (i + 1, grid_score))
    logger.debug('Best score (E_val): %s', grid.best_score_)
    logger.debug('Best params: %s', grid.best_params_)

    IO.cache(grid, Path.of_cache('gbdt_search.GridSearchCV.pkl'))

    X_test = dataset.load_test()
    raw_scaler.fit(np.r_[X, X_test])
    X_scaled = raw_scaler.transform(X)

    params.update(grid.best_params_)
    clf = GradientBoostingClassifier(**params)
    clf.fit(X_scaled, y)

    logger.debug('E_in: %f', Util.auc_score(grid, X_scaled, y))
    IO.dump_submission(Pipeline([('scaler', raw_scaler),
                                 ('gbdt', grid)]), 'gbdt_search_0707_01')
示例#15
0
def gbdt_grid():
    """
    Grid search for best params.
    Best params: {'learning_rate': 0.05, 'subsample': 0.3}
    Submission: gbdt_grid_0706_03.csv
    E_val: 0.860118290628
    E_in: 0.882949
    E_out: 0.8809314555068068
    """
    from sklearn.ensemble import GradientBoostingClassifier
    from sklearn.preprocessing import StandardScaler
    from sklearn.grid_search import GridSearchCV
    from sklearn.cross_validation import StratifiedKFold
    from sklearn.pipeline import Pipeline
    import numpy as np

    X, y = dataset.load_train()
    raw_scaler = StandardScaler()
    X_scaled = raw_scaler.fit_transform(X)

    param_grid = {
        'learning_rate': [0.05, 0.1],
        'subsample': [0.3, 0.5, 0.7]
    }

    grid = GridSearchCV(GradientBoostingClassifier(n_estimators=3000),
                        param_grid, scoring='roc_auc', n_jobs=-1,
                        cv=StratifiedKFold(y, 5), refit=False, verbose=1)
    grid.fit(X_scaled, y)

    logger.debug('Got best GBDT.')
    logger.debug('Grid scores: %s', grid.grid_scores_)
    logger.debug('Best score (E_val): %s', grid.best_score_)
    logger.debug('Best params: %s', grid.best_params_)

    X_test = dataset.load_test()
    raw_scaler.fit_transform(np.r_[X, X_test])
    X_scaled = raw_scaler.transform(X)

    clf = GradientBoostingClassifier(**grid.best_params_)
    clf.fit(X_scaled, y)

    IO.cache(grid, Path.of_cache('gbdt_grid.GridSearchCV.pkl'))

    logger.debug('E_in: %f', Util.auc_score(clf, X_scaled, y))
    IO.dump_submission(Pipeline([('scaler', raw_scaler),
                                 ('gbdt', clf)]), 'gbdt_grid_0706_03')
示例#16
0
def gbdt():
    """
    Submission: gbdt_0708_02.csv
    n_estimators: 1000, learning_rate: 0.1, subsample: 0.5
    E_val: 0.858235
    E_in: 0.908622
    E_out: 0.8873906795559863
    n_estimators: 500, learning_rate: 0.1, subsample: 0.5
    E_val: 0.870976
    E_in: 0.899593
    E_out: 0.88711101837711
    n_estimators: 3000, learning_rate: 0.1, subsample: 0.5
    E_val: 0.836049
    E_in: 0.936056
    E_out: 0.8833930861722906

    depth=4; n_estimators: 1000, learning_rate: 0.1, subsample: 0.5
    E_val: 0.947301
    E_in: 0.983812 (on depth=4) // 0.85089646325496504 (on depth=0)
    E_out: 0.8855316272153549
    """
    from sklearn.ensemble import GradientBoostingClassifier
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    import numpy as np

    gb = GradientBoostingClassifier(n_estimators=1000, learning_rate=0.1,
                                    subsample=0.5)

    d = 0
    X, y = dataset.load_train(depth=d)
    raw_scaler = StandardScaler()
    raw_scaler.fit(np.r_[X, dataset.load_test()])
    X_scaled = raw_scaler.transform(X)
    gb.fit(X_scaled, y)

    IO.cache(gb, Path.of_cache('gbdt.GradientBoostingClassifier.d%d.pkl' % d))
    IO.dump_submission(Pipeline([('scaler', raw_scaler), ('gbdt', gb)]),
                       'gbdt_0708_02.1000.d%d' % d)

    logger.debug('E_in(full): %f', Util.auc_score(gb, X_scaled, y))

    X, y = dataset.load_train()
    X_scaled = raw_scaler.transform(X)
    logger.debug('E_in(depth=0): %f', Util.auc_score(gb, X_scaled, y))
示例#17
0
def extract(base_date):
    pkl_path = Path.of_cache('sessions.%s.pkl' % base_date)
    X = IO.fetch_cache(pkl_path)
    if X is not None:
        logger.debug('cache hit')
        return X

    logger.debug('cache missed')
    logger.debug('prepare datasets ...')

    enroll_all = IO.load_enrollments()
    log_all = IO.load_logs()

    log_all = log_all[log_all['time'] <= base_date]

    logger.debug('datasets prepared')

    check_dataframe = Util.dataframe_checker(logger)

    n_proc = par.cpu_count()
    params = [(log_all, dt)
              for dt in [timedelta(hours=3), timedelta(hours=1),
                         timedelta(hours=12), timedelta(days=1),
                         timedelta(days=7)]]
    log_problem = log_all[log_all['event'] == 'problem']
    params += [(log_problem, dt)
               for dt in [timedelta(hours=3), timedelta(hours=1)]]
    pool = par.Pool(processes=min(n_proc, len(params)))
    X = enroll_all
    for dt, X_ in pool.map(__get_features__, params):
        check_dataframe(X_, str(dt))
        X = pd.merge(X, X_, how='left', on='enrollment_id')

    pool.close()
    pool.join()

    del X['username']
    del X['course_id']

    X.fillna(0, inplace=True)
    check_dataframe(X, 'X')
    IO.cache(X, pkl_path)

    return X
示例#18
0
def erf():
    """
    Submission: erf_0705_01.csv
    3000 trees
    E_val: 0.870800
    E_in: 0.999998
    E_out:
    15000 trees
    E_val:
    E_in:
    E_out:
    """
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.ensemble import ExtraTreesClassifier

    X, y = dataset.load_train()

    raw_scaler = StandardScaler()
    raw_scaler.fit(X)
    X_scaled = raw_scaler.transform(X)
    del X

    rf = ExtraTreesClassifier(n_estimators=3000, oob_score=True, n_jobs=-1,
                              class_weight='auto', bootstrap=True)
    rf.fit(X_scaled, y)

    logger.debug('ExtraTreesClassifier fitted')

    import gc
    gc.collect()

    logger.debug('Eval(oob): %f', rf.oob_score_)
    logger.debug('Ein: %f', Util.auc_score(rf, X_scaled, y))

    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('erf', rf)]), 'erf_0705_01')

    logger.debug('caching fitted ExtraTreesClassifier')
    IO.cache(rf, Path.of_cache('erf.ExtraTreesClassifier.auto.pkl'))
    logger.debug('cached fitted ExtraTreesClassifier')
示例#19
0
def lr_with_fs1():
    """
    Submission: lr_with_fs1_0703_03.csv
    E_val:
    E_in: 0.876954
    E_out:
    """
    from sklearn.linear_model import LogisticRegressionCV, LogisticRegression
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline

    X, y = dataset.load_train()

    raw_scaler = StandardScaler()
    raw_scaler.fit(X)
    X_scaled = raw_scaler.transform(X)

    pkl_path = Path.of_cache('lr_with_fs1.LR.FS.pkl')
    lr = IO.fetch_cache(pkl_path)
    if lr is None:
        lr = LogisticRegression(class_weight='auto')
        lr.fit(X_scaled, y)
        IO.cache(lr, pkl_path)

    X_pruned = lr.transform(X_scaled)

    new_scaler = StandardScaler()
    new_scaler.fit(X_pruned)
    X_new = new_scaler.transform(X_pruned)

    clf = LogisticRegressionCV(cv=10, scoring='roc_auc', n_jobs=-1)
    clf.fit(X_new, y)

    print('CV scores: %s' % clf.scores_)
    print('Ein: %f' % Util.auc_score(clf, X_new, y))

    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('fs', lr),
                                 ('scale_new', new_scaler),
                                 ('lr', clf)]), 'lr_with_fs1_0703_03')
示例#20
0
def load_test():
    """
    Load dataset for testing.


    Returns
    -------
    X: numpy ndarray, shape: (num_of_enrollments, num_of_features)
    Rows of features.
    """
    logger.debug('loading test set')

    pkl_path = Path.of_cache('test_X.pkl')
    X = IO.fetch_cache(pkl_path)

    if X is None:
        base_date = datetime(2014, 8, 1, 22, 0, 47)
        X = IO.load_enrollment_test()
        for f in features.METHODS:
            X_ = f.extract(base_date)
            if X_ is None:
                print('%s returns None' % repr(f.__name__))
                continue
            if np.any(pd.isnull(X_)):
                raise RuntimeError('%s can generate NA(s)' % repr(f.__name__))

            X = pd.merge(X, X_, how='left', on='enrollment_id')
            if np.any(pd.isnull(X)):
                raise RuntimeError('%s does not generate features of all '
                                   'enrollments' % repr(f.__name__))

        del X['enrollment_id']
        del X['username']
        del X['course_id']
        X = X.as_matrix()

        IO.cache(X, pkl_path)

    logger.debug('test set loaded')
    return X
示例#21
0
def erf2():
    """
    Submission: erf2_0705_02.csv
    3000 trees
    E_val: [0.83766072, 0.89704662, 0.85299486, 0.8639041, 0.82955865]
    E_in: 1.000000
    E_out:
    """
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.ensemble import ExtraTreesClassifier
    from sklearn.cross_validation import cross_val_score

    X, y = dataset.load_train()

    raw_scaler = StandardScaler()
    raw_scaler.fit(X)
    X_scaled = raw_scaler.transform(X)

    del X
    import gc
    gc.collect()

    erf = ExtraTreesClassifier(n_estimators=3000, n_jobs=-1,
                               class_weight='auto')
    scores = cross_val_score(erf, X_scaled, y, cv=5, n_jobs=-1)
    logger.debug('CV: %s', scores)
    logger.debug('Eval: %f', sum(scores) / len(scores))

    erf.fit(X_scaled, y)
    logger.debug('ExtraTreesClassifier fitted')
    logger.debug('Ein: %f', Util.auc_score(erf, X_scaled, y))

    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('erf', erf)]), 'erf2_0705_02')

    logger.debug('caching fitted ExtraTreesClassifier')
    IO.cache(erf, Path.of_cache('erf2.ExtraTreesClassifier.auto.pkl'))
    logger.debug('cached fitted ExtraTreesClassifier')
示例#22
0
    def grep(self, string, searchPath):
        # Figure out if we're executig a local grep, or remote grep via ssh
        #(user, host, searchPath) = self.remote_params(searchPath)
        #self.is_remote = (user != None)
        
        self.cancelled = False
        self.check_regex(string)
        searchPath = Path.full(searchPath)
    
        # Construct args for grep command execution
        argList = self.build_grep_args(string, searchPath)
        #if self.is_remote:
        #    argList = self.build_ssh_args(user, host) + argList
        
        # Run command
        stdErrFile = tempfile.TemporaryFile()
        stdOutFile = tempfile.TemporaryFile()
        self.grepProc = subprocess.Popen(argList, stdout=stdOutFile, stderr=stdErrFile)
        self.grepProc.wait()
        
        # Handle case where operation was cancelled
        if self.grepProc.returncode < 0:
            return
        
        # Read data from stdout/stderror
        stdOutFile.seek(0)
        output = stdOutFile.read().decode('utf-8', 'replace')
        stdOutFile.close()
        stdErrFile.seek(0)
        errMsg = stdErrFile.read()
        stdErrFile.close()
        
        if self.grepProc.returncode == 1:
            raise NoResultsException()
        if self.grepProc.returncode > 1:
            raise GrepException(errMsg)

        return self.parse_output(output, searchPath, string, self.is_remote)
示例#23
0
def knn():
    """
    Submission: knn_0704_01.csv
    E_val:
    E_in:
    E_out:
    """
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.cross_validation import StratifiedKFold
    from sklearn.grid_search import GridSearchCV
    from sklearn.neighbors import KNeighborsClassifier
    import numpy as np

    X, y = dataset.load_train()

    raw_scaler = StandardScaler()
    raw_scaler.fit(X)
    X_scaled = raw_scaler.transform(X)

    knn = KNeighborsClassifier()
    params = {
        'n_neighbors': np.arange(5, 51, 5),
        'weights': ['uniform', 'distance'],
        'leaf_size': np.arange(30, 201, 10)
    }
    grid = GridSearchCV(knn, params, scoring='roc_auc', n_jobs=-1,
                        cv=StratifiedKFold(y, 5))
    grid.fit(X_scaled, y)

    logger.debug('Got best kNN.')
    logger.debug('Grid scores: %s', grid.grid_scores_)
    logger.debug('Best score (E_val): %s', grid.best_score_)
    logger.debug('Best params: %s', grid.best_params_)
    IO.cache(grid, Path.of_cache('knn.GridSearchCV.KNeighborsClassifier.pkl'))

    IO.dump_submission(Pipeline([('scale_raw', raw_scaler),
                                 ('knn', grid)]), 'knn_0704_01')
示例#24
0
 def activate_result(self, itr):
     if not self.results or self.results.is_remote: return True
     if len(self.results) <= itr.get_line():
         return True
     result = self.results[itr.get_line()]
     
     for tag in itr.get_tags(): # FIXME: Create a findTagByType function?
         if tag.get_property('name') == 'link':
             (itr, itr_end) = self.get_tag_pos(itr, tag)
             filename = self.getTextBuffer().get_text(itr, itr_end, False)
             filename = os.path.join(self.results.search_path, filename)
             filename = Path.full(filename)
             
             cmdList = []
             for itm in self.app.prefs.get('editor').split(' '):
                 if '$1' in itm:
                     itm = itm.replace('$1', filename)
                 if '$n' in itm:
                     itm = itm.replace('$n', result.linenum)
                 cmdList.append(itm)
             subprocess.Popen(cmdList)
             return True
     return False
示例#25
0
    def parse_output(self, output, searchPath, searchString, is_remote):
        results = GrepResults()
        results.search_path = searchPath
        results.search_string = searchString
        results.is_remote = is_remote

        for line in output.splitlines():
            (filename, sep, rest) = line.partition(':')
            (linenum, sep, text) = rest.partition(':')
            
            if (not filename) or (not text) or (not linenum):
                continue
            if (self.max_matches > 0) and len(results) == self.max_matches:
                break
            
            # Ignore case where we have malformed data in output
            try:
                int(linenum)
            except:
                continue
            
            results.append(GrepResult(Path.relativeTo(filename, searchPath), text, linenum))
        return results
示例#26
0
 def cmd(g, end, off):
     return Path.Command(g, {'X': end.x, 'Y': end.y, 'Z': end.z, 'I': off.x, 'J': off.y, 'K': off.z})
示例#27
0
    def testLinuxCNC(self):
        # first create something to generate a path for
        box = self.doc.addObject("Part::Box", "Box")

        # Create job and setup tool library + default tool
        job = self.doc.addObject("Path::FeatureCompoundPython", "Job")
        PathScripts.PathJob.ObjectPathJob(job, box, None)
        PathScripts.PathToolController.CommandPathToolController.Create(
            job.Name, False)
        tool1 = Path.Tool()
        tool1.Diameter = 5.0
        tool1.Name = "Default Tool"
        tool1.CuttingEdgeHeight = 15.0
        tool1.ToolType = "EndMill"
        tool1.Material = "HighSpeedSteel"

        tc = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", 'TC')
        PathScripts.PathToolController.ToolController(tc)
        PathScripts.PathUtils.addToJob(tc, "Job")
        tc.Tool = tool1
        tc.ToolNumber = 2

        self.failUnless(True)

        self.doc.getObject("TC").ToolNumber = 2
        self.doc.recompute()

        contour = self.doc.addObject("Path::FeaturePython", "Contour")
        PathScripts.PathContour.ObjectContour(contour)
        contour.Active = True
        contour.ClearanceHeight = 20.0
        contour.StepDown = 1.0
        contour.StartDepth = 10.0
        contour.FinalDepth = 0.0
        contour.SafeHeight = 12.0
        contour.OffsetExtra = 0.0
        contour.Direction = 'CW'
        contour.ToolController = tc
        contour.UseComp = False
        PathScripts.PathUtils.addToJob(contour)
        PathScripts.PathContour.ObjectContour.setDepths(contour.Proxy, contour)
        self.doc.recompute()

        job.PostProcessor = 'linuxcnc'
        job.PostProcessorArgs = '--no-header --no-line-numbers --no-comments --no-show-editor --output-precision=2'

        post = PathScripts.PathPost.CommandPathPost()
        (fail, gcode) = post.exportObjectsWith([job], job, False)
        self.assertFalse(fail)

        referenceFile = FreeCAD.getHomePath(
        ) + 'Mod/Path/PathTests/test_linuxcnc_00.ngc'
        with open(referenceFile, 'r') as fp:
            refGCode = fp.read()

        # Use if this test fails in order to have a real good look at the changes
        if False:
            with open('tab.tmp', 'w') as fp:
                fp.write(gcode)

        if gcode != refGCode:
            msg = ''.join(
                difflib.ndiff(gcode.splitlines(True),
                              refGCode.splitlines(True)))
            self.fail("linuxcnc output doesn't match: " + msg)
示例#28
0
    def PerformCutBoolean(self):
        if self.resetSimulation:
            self.resetSimulation = False
            self.SetupSimulation()

        if self.busy:
            return
        self.busy = True

        cmd = self.operation.Path.Commands[self.icmd]
        pathSolid = None

        if cmd.Name in ["G0"]:
            self.firstDrill = True
            self.curpos = self.RapidMove(cmd, self.curpos)
        if cmd.Name in ["G1", "G2", "G3"]:
            self.firstDrill = True
            if self.skipStep:
                self.curpos = self.RapidMove(cmd, self.curpos)
            else:
                (pathSolid,
                 self.curpos) = self.GetPathSolid(self.tool, cmd, self.curpos)

        if cmd.Name in ["G80"]:
            self.firstDrill = True
        if cmd.Name in ["G73", "G81", "G82", "G83"]:
            if self.firstDrill:
                extendcommand = Path.Command("G0", {"Z": cmd.r})
                self.curpos = self.RapidMove(extendcommand, self.curpos)
                self.firstDrill = False
            extendcommand = Path.Command("G0", {
                "X": cmd.x,
                "Y": cmd.y,
                "Z": cmd.r
            })
            self.curpos = self.RapidMove(extendcommand, self.curpos)
            extendcommand = Path.Command("G1", {
                "X": cmd.x,
                "Y": cmd.y,
                "Z": cmd.z
            })
            self.curpos = self.RapidMove(extendcommand, self.curpos)
            extendcommand = Path.Command("G1", {
                "X": cmd.x,
                "Y": cmd.y,
                "Z": cmd.r
            })
            self.curpos = self.RapidMove(extendcommand, self.curpos)
        self.skipStep = False
        if pathSolid is not None:
            if self.debug:
                self.cutSolid.Shape = pathSolid
            newStock = self.stock.cut([pathSolid], 1e-3)
            try:
                if newStock.isValid():
                    self.stock = newStock.removeSplitter()
            except Exception:
                if self.debug:
                    print("invalid cut at cmd #{}".format(self.icmd))
        if not self.disableAnim:
            self.cutTool.Placement = FreeCAD.Placement(self.curpos,
                                                       self.stdrot)
        self.icmd += 1
        self.iprogress += 1
        self.UpdateProgress()
        if self.icmd >= len(self.operation.Path.Commands):
            self.ioperation += 1
            if self.ioperation >= len(self.activeOps):
                self.EndSimulation()
                return
            else:
                self.SetupOperation(self.ioperation)
        if not self.disableAnim:
            self.cutMaterial.Shape = self.stock
        self.busy = False
示例#29
0
    def opExecute(self, obj):
        '''opExecute(obj) ... process engraving operation'''
        PathLog.track()

        jobshapes = []

        if len(obj.Base) >= 1:  # user has selected specific subelements
            PathLog.track(len(obj.Base))
            wires = []
            for base, subs in obj.Base:
                edges = []
                basewires = []
                for feature in subs:
                    sub = base.Shape.getElement(feature)
                    if type(sub) == Part.Edge:
                        edges.append(sub)
                    elif sub.Wires:
                        basewires.extend(sub.Wires)
                    else:
                        basewires.append(Part.Wire(sub.Edges))

                for edgelist in Part.sortEdges(edges):
                    basewires.append(Part.Wire(edgelist))

                wires.extend(basewires)
                jobshapes.append(Part.makeCompound(wires))

        elif len(obj.BaseShapes) > 0:  # user added specific shapes
            jobshapes.extend([base.Shape for base in obj.BaseShapes])
        else:
            PathLog.track(self.model)
            for base in self.model:
                PathLog.track(base.Label)
                if base.isDerivedFrom('Part::Part2DObject'):
                    jobshapes.append(base.Shape)
                elif base.isDerivedFrom('Sketcher::SketchObject'):
                    jobshapes.append(base.Shape)
                elif hasattr(base, 'ArrayType'):
                    jobshapes.append(base.Shape)
                elif isinstance(base.Proxy, ArchPanel.PanelSheet):
                    for tag in self.model[0].Proxy.getTags(self.model[0],
                                                           transform=True):
                        tagWires = []
                        for w in tag.Wires:
                            tagWires.append(Part.Wire(w.Edges))
                        jobshapes.append(Part.makeCompound(tagWires))

        if len(jobshapes) > 0:
            PathLog.debug('processing {} jobshapes'.format(len(jobshapes)))
            wires = []
            for shape in jobshapes:
                shapeWires = shape.Wires
                PathLog.debug('jobshape has {} edges'.format(len(shape.Edges)))
                self.commandlist.append(
                    Path.Command('G0', {
                        'Z': obj.ClearanceHeight.Value,
                        'F': self.vertRapid
                    }))
                self.buildpathocc(obj, shapeWires, self.getZValues(obj))
                wires.extend(shapeWires)
            self.wires = wires
            PathLog.debug('processing {} jobshapes -> {} wires'.format(
                len(jobshapes), len(wires)))
        # the last command is a move to clearance, which is automatically added by PathOp
        if self.commandlist:
            self.commandlist.pop()
示例#30
0
        # update base_date and enroll_ids
        base_date -= Dw
        enroll_ids = __enroll_ids_with_log__(log_all, enroll_ids, base_date)

    logger.debug('train set loaded')

    if np.any(np.isinf(X)):
        logger.debug('train set has INF')
    return X, y


if __name__ == '__main__':
    import glob
    if sys.argv[1] == 'clean':
        cached_files = glob.glob(Path.of_cache('train_X*.pkl'))
        cached_files += glob.glob(Path.of_cache('train_y*.pkl'))
        cached_files += glob.glob(Path.of_cache('test_X.pkl'))
        for f in cached_files:
            print('Removing %s ...' % f)
            os.remove(f)

    elif sys.argv[1] == 'gen':
        d = 1
        if len(sys.argv) > 2:
            d = int(sys.argv[2])
        print('depth: %d' % d)
        X, y = load_train(depth=d)
        print('X.shape: %d x %d' % X.shape)
        print('y.shape: %d' % y.shape)
        X_test = load_test()
示例#31
0
    def execute(self, obj):
        PathLog.track()
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        toolLoad = obj.ToolController
        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(toolLoad)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
                return
            else:
                self.radius = tool.Diameter/2

        if len(obj.Names) == 0:
            parentJob = PathUtils.findParentJob(obj)
            if parentJob is None:
                return
            baseobject = parentJob.Base
            if baseobject is None:
                return

            # Arch PanelSheet
            if hasattr(baseobject, "Proxy"):
                holes = []
                if isinstance(baseobject.Proxy, ArchPanel.PanelSheet):
                    baseobject.Proxy.execute(baseobject)
                    i = 0
                    holeshapes = baseobject.Proxy.getHoles(baseobject, transform=True)
                    tooldiameter = obj.ToolController.Proxy.getTool(obj.ToolController).Diameter
                    for holeshape in holeshapes:
                        PathLog.debug('Entering new HoleShape')
                        for wire in holeshape.Wires:
                            PathLog.debug('Entering new Wire')
                            for edge in wire.Edges:
                                if PathUtils.isDrillable(baseobject, edge, tooldiameter):
                                    PathLog.debug('Found drillable hole edges: {}'.format(edge))
                                    x = edge.Curve.Center.x
                                    y = edge.Curve.Center.y
                                    diameter = edge.BoundBox.XLength
                                    holes.append({'x': x, 'y': y, 'featureName': baseobject.Name+'.'+'Drill'+str(i), 'd': diameter})
                                    i = i + 1
            else:
                holes = self.findHoles(obj, baseobject.Shape)
                for i in range(len(holes)):
                    holes[i]['featureName'] = baseobject.Name + '.' + holes[i]['featureName']
            names = []
            positions = []
            enabled = []
            diameters = []
            for h in holes:
                if len(names) == 0:
                    self.findHeights(obj, baseobject, h)
                names.append(h['featureName'])
                positions.append(FreeCAD.Vector(h['x'], h['y'], 0))
                enabled.append(1)
                diameters.append(h['d'])
            obj.Names = names
            obj.Positions = positions
            obj.Enabled = enabled
            obj.Diameters = diameters

        locations = []
        output = "(Begin Drilling)\n"

        for i in range(len(obj.Names)):
            if obj.Enabled[i] > 0:
                locations.append({'x': obj.Positions[i].x, 'y': obj.Positions[i].y})
        if len(locations) > 0:
            locations = PathUtils.sort_jobs(locations, ['x', 'y'])
            output += "G90 G98\n"
            # rapid to clearance height
            output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            # rapid to first hole location, with spindle still retracted:

            p0 = locations[0]
            output += "G0 X" + fmt(p0['x']) + " Y" + fmt(p0['y']) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            pword = ""
            qword = ""
            if obj.PeckDepth.Value > 0 and obj.PeckEnabled:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            elif obj.DwellTime > 0 and obj.DwellEnabled:
                cmd = "G82"
                pword = " P" + fmt(obj.DwellTime)
            else:
                cmd = "G81"
            for p in locations:
                output += cmd + \
                    " X" + fmt(p['x']) + \
                    " Y" + fmt(p['y']) + \
                    " Z" + fmt(obj.FinalDepth.Value) + qword + pword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
示例#32
0
def Execute(op, obj):
    global sceneGraph
    global topZ

    sceneGraph = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()

    Console.PrintMessage("*** Adaptive toolpath processing started...\n")

    #hide old toolpaths during recalculation
    obj.Path = Path.Path("(Calculating...)")

    #store old visibility state
    job = op.getJob(obj)
    oldObjVisibility = obj.ViewObject.Visibility
    oldJobVisibility = job.ViewObject.Visibility

    obj.ViewObject.Visibility = False
    job.ViewObject.Visibility = False

    FreeCADGui.updateGui()
    try:
        helixDiameter = obj.HelixDiameterLimit.Value
        topZ = op.stock.Shape.BoundBox.ZMax
        obj.Stopped = False
        obj.StopProcessing = False
        if obj.Tolerance < 0.001:
            obj.Tolerance = 0.001

        pathArray = []
        for base, subs in obj.Base:
            for sub in subs:
                shape = base.Shape.getElement(sub)
                for edge in shape.Edges:
                    pathArray.append([discretize(edge)])

        #pathArray=connectEdges(edges)
        path2d = convertTo2d(pathArray)

        stockPaths = []
        if op.stock.StockType == "CreateCylinder":
            stockPaths.append([discretize(op.stock.Shape.Edges[0])])

        else:
            stockBB = op.stock.Shape.BoundBox
            v = []
            v.append(FreeCAD.Vector(stockBB.XMin, stockBB.YMin, 0))
            v.append(FreeCAD.Vector(stockBB.XMax, stockBB.YMin, 0))
            v.append(FreeCAD.Vector(stockBB.XMax, stockBB.YMax, 0))
            v.append(FreeCAD.Vector(stockBB.XMin, stockBB.YMax, 0))
            v.append(FreeCAD.Vector(stockBB.XMin, stockBB.YMin, 0))
            stockPaths.append([v])

        stockPath2d = convertTo2d(stockPaths)

        opType = area.AdaptiveOperationType.ClearingInside
        if obj.OperationType == "Clearing":
            if obj.Side == "Outside":
                opType = area.AdaptiveOperationType.ClearingOutside

            else:
                opType = area.AdaptiveOperationType.ClearingInside

        else:  # profiling
            if obj.Side == "Outside":
                opType = area.AdaptiveOperationType.ProfilingOutside

            else:
                opType = area.AdaptiveOperationType.ProfilingInside

        keepToolDownRatio = 3.0
        if hasattr(obj, 'KeepToolDownRatio'):
            keepToolDownRatio = float(obj.KeepToolDownRatio)

        # put here all properties that influence calculation of adaptive base paths,

        inputStateObject = {
            "tool": float(op.tool.Diameter),
            "tolerance": float(obj.Tolerance),
            "geometry": path2d,
            "stockGeometry": stockPath2d,
            "stepover": float(obj.StepOver),
            "effectiveHelixDiameter": float(helixDiameter),
            "operationType": obj.OperationType,
            "side": obj.Side,
            "forceInsideOut": obj.ForceInsideOut,
            "keepToolDownRatio": keepToolDownRatio,
            "stockToLeave": float(obj.StockToLeave)
        }

        inputStateChanged = False
        adaptiveResults = None

        if obj.AdaptiveOutputState != None and obj.AdaptiveOutputState != "":
            adaptiveResults = obj.AdaptiveOutputState

        if json.dumps(obj.AdaptiveInputState) != json.dumps(inputStateObject):
            inputStateChanged = True
            adaptiveResults = None

        # progress callback fn, if return true it will stop processing
        def progressFn(tpaths):
            for path in tpaths:  #path[0] contains the MotionType, #path[1] contains list of points
                if path[0] == area.AdaptiveMotionType.Cutting:
                    sceneDrawPath(path[1], (0, 0, 1))

                else:
                    sceneDrawPath(path[1], (1, 0, 1))

            FreeCADGui.updateGui()

            return obj.StopProcessing

        start = time.time()

        if inputStateChanged or adaptiveResults == None:
            a2d = area.Adaptive2d()
            a2d.stepOverFactor = 0.01 * obj.StepOver
            a2d.toolDiameter = float(op.tool.Diameter)
            a2d.helixRampDiameter = helixDiameter
            a2d.keepToolDownDistRatio = keepToolDownRatio
            a2d.stockToLeave = float(obj.StockToLeave)
            a2d.tolerance = float(obj.Tolerance)
            a2d.forceInsideOut = obj.ForceInsideOut
            a2d.opType = opType

            # EXECUTE
            results = a2d.Execute(stockPath2d, path2d, progressFn)

            # need to convert results to python object to be JSON serializable
            adaptiveResults = []
            for result in results:
                adaptiveResults.append({
                    "HelixCenterPoint":
                    result.HelixCenterPoint,
                    "StartPoint":
                    result.StartPoint,
                    "AdaptivePaths":
                    result.AdaptivePaths,
                    "ReturnMotionType":
                    result.ReturnMotionType
                })

        # GENERATE
        GenerateGCode(op, obj, adaptiveResults, helixDiameter)

        if not obj.StopProcessing:
            Console.PrintMessage("*** Done. Elapsed time: %f sec\n\n" %
                                 (time.time() - start))
            obj.AdaptiveOutputState = adaptiveResults
            obj.AdaptiveInputState = inputStateObject

        else:
            Console.PrintMessage(
                "*** Processing cancelled (after: %f sec).\n\n" %
                (time.time() - start))

    finally:
        obj.ViewObject.Visibility = oldObjVisibility
        job.ViewObject.Visibility = oldJobVisibility
        sceneClean()
示例#33
0
    def opExecute(self, obj, getsim=False):
        '''opExecute(obj, getsim=False) ... implementation of Path.Area ops.
        determines the parameters for _buildPathArea().
        Do not overwrite, implement
            areaOpAreaParams(obj, isHole) ... op specific area param dictionary
            areaOpPathParams(obj, isHole) ... op specific path param dictionary
            areaOpShapes(obj)             ... the shape for path area to process
            areaOpUseProjection(obj)      ... return true if operation can use projection
        instead.'''
        PathLog.track()
        self.endVector = None
        PathLog.debug("opExecute() in PathAreaOp.py")

        # Instantiate class variables for operation reference
        self.rotateFlag = False
        self.modelName = None
        self.leadIn = 2.0  # safOfset / 2.0

        # Initialize depthparams
        finish_step = obj.FinishDepth.Value if hasattr(obj,
                                                       "FinishDepth") else 0.0
        self.depthparams = PathUtils.depth_params(
            clearance_height=obj.ClearanceHeight.Value,
            safe_height=obj.SafeHeight.Value,
            start_depth=obj.StartDepth.Value,
            step_down=obj.StepDown.Value,
            z_finish_step=finish_step,
            final_depth=obj.FinalDepth.Value,
            user_depths=None)

        # Recalculate operation heights for rotational operation
        if obj.UseRotation != 'Off':
            # Calculate operation heights based upon rotation radii
            opHeights = self.opDetermineRotationRadii(
                obj
            )  # return is [(xRotRad, yRotRad, zRotRad), (clrOfst, safOfst)]
            (xRotRad, yRotRad, zRotRad) = opHeights[0]
            (clrOfst, safOfset) = opHeights[1]
            # self.leadIn = 0.0 #safOfset / 2.0

            # Set clearnance and safe heights based upon rotation radii
            obj.ClearanceHeight.Value = xRotRad + clrOfst
            obj.SafeHeight.Value = xRotRad + safOfset
            if yRotRad > xRotRad:
                obj.ClearanceHeight.Value = yRotRad + clrOfst
                obj.SafeHeight.Value = yRotRad + safOfset

            # Set axial feed rates based upon horizontal feed rates
            safeCircum = 2 * math.pi * obj.SafeHeight.Value
            self.axialFeed = 360 / safeCircum * self.horizFeed
            self.axialRapid = 360 / safeCircum * self.horizRapid

        # Set start point
        if PathOp.FeatureStartPoint & self.opFeatures(
                obj) and obj.UseStartPoint:
            start = obj.StartPoint
        else:
            start = None

        aOS = self.areaOpShapes(
            obj)  # list of tuples (shape, isHole, sub, angle, axis, tag)

        # Adjust tuples length received from other PathWB tools/operations beside PathPocketShape
        shapes = []
        for shp in aOS:
            if len(shp) == 2:
                (fc, iH) = shp
                tup = fc, iH, 'notPocket', 0.0, 'X'
                shapes.append(tup)
            else:
                shapes.append(shp)

        if len(shapes) > 1:
            jobs = [{
                'x': s[0].BoundBox.XMax,
                'y': s[0].BoundBox.YMax,
                'shape': s
            } for s in shapes]

            jobs = PathUtils.sort_jobs(jobs, ['x', 'y'])

            shapes = [j['shape'] for j in jobs]

        sims = []
        for (shape, isHole, sub, angle, axis) in shapes:
            startDep = obj.StartDepth.Value  # + safOfset
            safeDep = obj.SafeHeight.Value
            clearDep = obj.ClearanceHeight.Value
            finalDep = obj.FinalDepth.Value  # finDep

            finish_step = obj.FinishDepth.Value if hasattr(
                obj, "FinishDepth") else 0.0
            self.depthparams = PathUtils.depth_params(
                clearance_height=clearDep,  # obj.ClearanceHeight.Value
                safe_height=safeDep,  # obj.SafeHeight.Value
                start_depth=startDep,
                step_down=obj.StepDown.Value,
                z_finish_step=finish_step,  # obj.FinalDepth.Value
                final_depth=finalDep,
                user_depths=None)

            try:
                (pp, sim) = self._buildPathArea(obj, shape, isHole, start,
                                                getsim)
                ppCmds = pp.Commands
                if obj.UseRotation != 'Off' and self.rotateFlag is True:
                    # Rotate model to index for cut
                    axisOfRot = 'A'
                    if axis == 'Y':
                        axisOfRot = 'B'
                        # Reverse angle temporarily to match model. Error in FreeCAD render of B axis rotations
                        if obj.B_AxisErrorOverride is True:
                            angle = -1 * angle
                    # Rotate Model to correct angle
                    ppCmds.insert(
                        0,
                        Path.Command('G0', {
                            axisOfRot: angle,
                            'F': self.axialFeed
                        }))
                    # Raise cutter to safe depth and return index to starting position
                    ppCmds.append(
                        Path.Command('G0', {
                            'Z': safeDep,
                            'F': self.vertRapid
                        }))
                    ppCmds.append(
                        Path.Command('G0', {
                            axisOfRot: 0.0,
                            'F': self.axialFeed
                        }))
                # Save gcode commands to object command list
                self.commandlist.extend(ppCmds)
                sims.append(sim)
            except Exception as e:
                FreeCAD.Console.PrintError(e)
                FreeCAD.Console.PrintError(
                    "Something unexpected happened. Check project and tool config."
                )

            if self.areaOpRetractTool(obj):
                self.endVector = None

        # Raise cutter to safe height and rotate back to original orientation
        if self.rotateFlag is True:
            self.commandlist.append(
                Path.Command('G0', {
                    'Z': obj.SafeHeight.Value,
                    'F': self.vertRapid
                }))
            self.commandlist.append(
                Path.Command('G0', {
                    'A': 0.0,
                    'F': self.axialFeed
                }))
            self.commandlist.append(
                Path.Command('G0', {
                    'B': 0.0,
                    'F': self.axialFeed
                }))
            FreeCAD.ActiveDocument.getObject(self.modelName).purgeTouched()

        PathLog.debug("obj.Name: " + str(obj.Name))
        return sims
示例#34
0
    def execute(self, obj):
        PathLog.track()

        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment) + ')\n'

        toolLoad = obj.ToolController

        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError(
                "No Tool Controller is selected. We need a tool to build a Path."
            )
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(
                toolLoad)  # PathUtils.getTool(obj, toolLoad.ToolNumber)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError(
                    "No Tool found or diameter is zero. We need a tool to build a Path."
                )
                return
            else:
                self.radius = tool.Diameter / 2

        wires = []

        parentJob = PathUtils.findParentJob(obj)
        if parentJob is None:
            return
        baseobject = parentJob.Base
        if baseobject is None:
            return
        try:
            if baseobject.isDerivedFrom('Sketcher::SketchObject') or \
                    baseobject.isDerivedFrom('Part::Part2DObject') or \
                    hasattr(baseobject, 'ArrayType'):

                output += "G0 Z" + PathUtils.fmt(
                    obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                        self.vertRapid) + "\n"

                # we only consider the outer wire if this is a Face
                for w in baseobject.Shape.Wires:
                    tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                    wires.append(Part.Wire(tempedges))

                if obj.Algorithm == "OCC Native":
                    output += self.buildpathocc(obj, wires)

            elif isinstance(baseobject.Proxy,
                            ArchPanel.PanelSheet):  # process the sheet

                shapes = baseobject.Proxy.getTags(baseobject, transform=True)
                for shape in shapes:
                    output += "G0 Z" + PathUtils.fmt(
                        obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                            self.vertRapid) + "\n"
                    for w in shape.Wires:
                        tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                        wires.append(Part.Wire(tempedges))
                    if obj.Algorithm == "OCC Native":
                        output += self.buildpathocc(obj, wires)
            else:
                raise ValueError('Unknown baseobject type for engraving')

            output += "G0 Z" + PathUtils.fmt(
                obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                    self.vertRapid) + "\n"

        except:
            FreeCAD.Console.PrintError(
                "The Job Base Object has no engraveable element.  Engraving operation will produce no output."
            )

        # print output
        if output == "":
            output += "(No commands processed)"

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
示例#35
0
def parse(pathobj):
    # pylint: disable=global-statement
    global PRECISION
    global MODAL
    global OUTPUT_DOUBLES
    global UNIT_FORMAT
    global UNIT_SPEED_FORMAT

    out = ""
    lastcommand = None
    precision_string = '.' + str(PRECISION) + 'f'
    currLocation = {}  # keep track for no doubles

    # the order of parameters
    # linuxcnc doesn't want K properties on XY plane  Arcs need work.
    params = [
        'X', 'Y', 'Z', 'A', 'B', 'C', 'I', 'J', 'F', 'S', 'T', 'Q', 'R', 'L',
        'H', 'D', 'P'
    ]
    firstmove = Path.Command("G0", {"X": -1, "Y": -1, "Z": -1, "F": 0.0})
    currLocation.update(firstmove.Parameters)  # set First location Parameters

    if hasattr(pathobj, "Group"):  # We have a compound or project.
        # if OUTPUT_COMMENTS:
        #     out += linenumber() + "(compound: " + pathobj.Label + ")\n"
        for p in pathobj.Group:
            out += parse(p)
        return out
    else:  # parsing simple path

        # groups might contain non-path things like stock.
        if not hasattr(pathobj, "Path"):
            return out

        # if OUTPUT_COMMENTS:
        #     out += linenumber() + "(" + pathobj.Label + ")\n"

        for c in pathobj.Path.Commands:

            outstring = []
            command = c.Name
            outstring.append(command)

            # if modal: suppress the command if it is the same as the last one
            if MODAL is True:
                if command == lastcommand:
                    outstring.pop(0)

            if c.Name[0] == '(' and not OUTPUT_COMMENTS:  # command is a comment
                continue

            # Now add the remaining parameters in order
            for param in params:
                if param in c.Parameters:
                    if param == 'F' and (
                            currLocation[param] != c.Parameters[param]
                            or OUTPUT_DOUBLES):
                        if c.Name not in [
                                "G0", "G00"
                        ]:  # linuxcnc doesn't use rapid speeds
                            speed = Units.Quantity(c.Parameters['F'],
                                                   FreeCAD.Units.Velocity)
                            if speed.getValueAs(UNIT_SPEED_FORMAT) > 0.0:
                                outstring.append(param + format(
                                    float(speed.getValueAs(UNIT_SPEED_FORMAT)),
                                    precision_string))
                        else:
                            continue
                    elif param == 'T':
                        outstring.append(param + str(int(c.Parameters['T'])))
                    elif param == 'H':
                        outstring.append(param + str(int(c.Parameters['H'])))
                    elif param == 'D':
                        outstring.append(param + str(int(c.Parameters['D'])))
                    elif param == 'S':
                        outstring.append(param + str(int(c.Parameters['S'])))
                    else:
                        if (not OUTPUT_DOUBLES) and (
                                param
                                in currLocation) and (currLocation[param]
                                                      == c.Parameters[param]):
                            continue
                        else:
                            pos = Units.Quantity(c.Parameters[param],
                                                 FreeCAD.Units.Length)
                            outstring.append(
                                param +
                                format(float(pos.getValueAs(UNIT_FORMAT)),
                                       precision_string))

            # store the latest command
            lastcommand = command
            currLocation.update(c.Parameters)

            # Check for Tool Change:
            if command == 'M6':
                # stop the spindle
                out += linenumber() + "M5\n"
                for line in TOOL_CHANGE.splitlines(True):
                    out += linenumber() + line

                # add height offset
                if USE_TLO:
                    tool_height = '\nG43 H' + str(int(c.Parameters['T']))
                    outstring.append(tool_height)

            if command == "message":
                if OUTPUT_COMMENTS is False:
                    out = []
                else:
                    outstring.pop(0)  # remove the command

            # prepend a line number and append a newline
            if len(outstring) >= 1:
                if OUTPUT_LINE_NUMBERS:
                    outstring.insert(0, (linenumber()))

                # append the line to the final output
                for w in outstring:
                    out += w + COMMAND_SPACE
                # Note: Do *not* strip `out`, since that forces the allocation
                # of a contiguous string & thus quadratic complexity.
                out += "\n"

        return out
示例#36
0
def extract(base_date):
    pkl_path = Path.of_cache('events.%s.pkl' % base_date)
    X = IO.fetch_cache(pkl_path)
    if X is not None:
        logger.debug('cache hit')
        return X

    logger.debug('cache missed')
    logger.debug('prepare datasets ...')

    enroll_all = IO.load_enrollments()
    log_all = IO.load_logs()

    log_all = log_all[log_all['time'] <= base_date]
    log_all['source_event'] = log_all['source'] + '-' + log_all['event']

    log_all = pd.merge(log_all, enroll_duration(log_all), how='left',
                       on='enrollment_id')
    log_all['day_diff'] = (log_all['time'] - log_all['st']).dt.days
    log_all['week_diff'] = log_all['day_diff'] // 7
    log_all['count'] = 1

    logger.debug('datasets prepared')

    log_last_week = log_all[
        log_all['time'] > log_all['et'] - timedelta(days=7)].copy()
    log_2nd_last_week = log_all[
        (log_all['time'] > log_all['et'] - timedelta(days=14)) &
        (log_all['time'] <= log_all['et'] - timedelta(days=7))].copy()
    log_first_week = log_all[
        log_all['time'] < log_all['st'] + timedelta(days=7)].copy()

    # 0~107: 用户在该课程的操作数量(按event_source序对统计),enrollment最后一周、
    # 倒数第二周、第一周、总体,占该用户在所有课程的比例,占该课程所有用户的比例
    # 114~125: numbers of events in the last week, the first week, and the week
    # before the last week of the enrollment; ratio on all courses by user;
    # ratio on all users by course
    EUC_last_week = count_source_event_features(log_last_week, enroll_all)
    EUC_2nd_last_week = count_source_event_features(log_2nd_last_week,
                                                    enroll_all)
    EUC_first_week = count_source_event_features(log_first_week, enroll_all)
    EUC_all = count_source_event_features(log_all, enroll_all)

    logger.debug('0~107, 114~125')

    # 108~111: 用户有行为的课程数量,用户行为的最后一周、倒数第二周、第一周、总体
    C_last_week = count_courses_by_user(log_last_week, enroll_all)
    C_2nd_last_week = count_courses_by_user(log_2nd_last_week, enroll_all)
    C_first_week = count_courses_by_user(log_first_week, enroll_all)
    C_all = count_courses_by_user(log_all, enroll_all)

    logger.debug('108~111')

    # 112: 课程的选课人数
    U_count = pd.merge(
        log_all, enroll_all, how='left', on='enrollment_id')\
        .groupby('course_id').agg({'username': lambda us: len(np.unique(us))})\
        .reset_index().rename(columns={'username': '******'})

    logger.debug('112')

    def f(group):
        from scipy.stats import linregress
        x = group['week_diff']
        c = group['count']
        if len(c) < 3:
            p = [0, 0]
        else:
            p = np.polyfit(x, c, 2)
        import warnings
        warnings.simplefilter('ignore', np.RankWarning)
        return pd.Series(
            [linregress(x, c)[0], np.mean(c), np.std(c), np.max(c),
             np.min(c), p[1], p[0]],
            index=['slope', 'mean', 'std', 'max', 'min', 'b', 'c'])

    # 113: trending slope of the weekly number of events within the enrollment
    # 126~129: average, standard deviation, maximal, minimal weekly numbers of
    # events in the enrollment period
    # 130~131: coefficients b and c in the polynomial model y = a + bx + cx**2,
    # where x is week number (all start from 0), and y is the weekly number of
    # events
    W_stats = log_all.groupby(['enrollment_id', 'week_diff'])\
        .agg({'count': np.sum}).reset_index().groupby('enrollment_id')\
        .apply(f).reset_index()
    W_stats.fillna(0, inplace=True)
    W_stats.ix[np.isinf(W_stats['c']), 'c'] = np.nanmax(
        W_stats[~np.isinf(W_stats['c'])])

    logger.debug('113, 126~129, 130~131')

    log_all['week_day'] = log_all['time'].dt.dayofweek
    log_all['hour'] = log_all['time'].dt.hour

    # 132~138: 7 counts of events in Monday to Sunday
    _E_TOTAL, _, _ = count_source_event(log_all, enroll_all)
    _E_TOTAL.rename(
        columns=lambda c: c + '_total' if c != 'enrollment_id' else c,
        inplace=True)
    WD = enroll_all
    for w in range(7):
        _E, _, _ = count_source_event(log_all[log_all['week_day'] == w],
                                      enroll_all)
        _E_W = pd.merge(_E, _E_TOTAL, how='left', on='enrollment_id')
        for se in SE_PAIRS:
            _E_W[se + '_ratio_se'] = _E_W[se] / _E_W[se + '_total']
            _E_W[se + '_ratio_day'] = _E_W[se] / _E_W['count']
        for c in _E_W.columns.values:
            if c.endswith('_total'):
                del _E_W[c]
        WD = pd.merge(WD, _E_W, how='left', on='enrollment_id')

    del WD['username']
    del WD['course_id']

    logger.debug('132~138')

    # 139~162: 24 counts of events in hour 0-23
    H = enroll_all
    for h in range(24):
        _E, _, _ = count_source_event(log_all[log_all['hour'] == h],
                                      enroll_all)
        _E_H = pd.merge(_E, _E_TOTAL, how='left', on='enrollment_id')
        for se in SE_PAIRS:
            _E_H[se + '_ratio_se'] = _E_H[se] / _E_H[se + '_total']
            _E_H[se + '_ratio_hour'] = _E_H[se] / _E_H['count']
        for c in _E_H.columns.values:
            if c.endswith('_total'):
                del _E_H[c]
        H = pd.merge(H, _E_H, how='left', on='enrollment_id')

    del H['username']
    del H['course_id']

    logger.debug('139~162')

    _EVENT_TOTAL = log_all.groupby('enrollment_id').agg({'count': np.sum})
    _EVENT_TOTAL.columns = ['total_events_count']
    _EVENT_TOTAL.reset_index(inplace=True)

    event_counts = log_all.groupby(['enrollment_id', 'event'])\
        .agg({'count': np.sum}).reset_index()
    event_types = ['access', 'page_close', 'problem', 'video', 'discussion',
                   'navigate', 'wiki']
    for e in event_types:
        event_counts[e] = 0
        event_counts.loc[event_counts['event'] == e, e] += \
            event_counts[event_counts['event'] == e]['count']
    del event_counts['event']
    del event_counts['count']

    # 163~169: 7 counts of event types
    E = event_counts.groupby('enrollment_id').agg(np.sum).reset_index()
    E = pd.merge(E, _EVENT_TOTAL, how='left', on='enrollment_id')
    for e in event_types:
        E[e + '_ratio'] = E[e] / E['total_events_count']
    del E['total_events_count']

    logger.debug('163~169')

    source_counts = log_all.groupby(['enrollment_id', 'source'])\
        .agg({'count': np.sum}).reset_index()
    for s in ['server', 'browser']:
        source_counts[s] = 0
        source_counts.loc[source_counts['source'] == s, s] += \
            source_counts[source_counts['source'] == s]['count']
    del source_counts['source']
    del source_counts['count']

    # 170~171: 2 counts of source types
    S = source_counts.groupby('enrollment_id').agg(np.sum).reset_index()
    S = pd.merge(S, _EVENT_TOTAL, how='left', on='enrollment_id')
    for s in ['server', 'browser']:
        S[s + '_ratio'] = S[s] / S['total_events_count']
    del S['total_events_count']

    logger.debug('170~171')

    logger.debug('composing to features')

    check_dataframe = Util.dataframe_checker(logger)

    check_dataframe(EUC_last_week, 'EUC_last_week')
    X = pd.merge(enroll_all, EUC_last_week, how='left', on='enrollment_id')

    check_dataframe(EUC_2nd_last_week, 'EUC_2nd_last_week')
    X = pd.merge(X, EUC_2nd_last_week, how='left', on='enrollment_id')

    check_dataframe(EUC_first_week, 'EUC_first_week')
    X = pd.merge(X, EUC_first_week, how='left', on='enrollment_id')

    check_dataframe(EUC_all, 'EUC_all')
    X = pd.merge(X, EUC_all, how='left', on='enrollment_id')

    check_dataframe(C_last_week, 'C_last_week')
    X = pd.merge(X, C_last_week, how='left', on='username')

    check_dataframe(C_2nd_last_week, 'C_2nd_last_week')
    X = pd.merge(X, C_2nd_last_week, how='left', on='username')

    check_dataframe(C_first_week, 'C_first_week')
    X = pd.merge(X, C_first_week, how='left', on='username')

    check_dataframe(C_all, 'C_all')
    X = pd.merge(X, C_all, how='left', on='username')

    check_dataframe(U_count, 'U_count')
    X = pd.merge(X, U_count, how='left', on='course_id')

    check_dataframe(W_stats, 'W_stats')
    X = pd.merge(X, W_stats, how='left', on='enrollment_id')

    check_dataframe(WD, 'WD')
    X = pd.merge(X, WD, how='left', on='enrollment_id')

    check_dataframe(H, 'H')
    X = pd.merge(X, H, how='left', on='enrollment_id')

    check_dataframe(E, 'E')
    X = pd.merge(X, E, how='left', on='enrollment_id')

    check_dataframe(S, 'S')
    X = pd.merge(X, S, how='left', on='enrollment_id')

    del X['username']
    del X['course_id']

    X.fillna(0, inplace=True)
    check_dataframe(X, 'X')
    IO.cache(X, pkl_path)

    return X
示例#37
0
    def _buildPathArea(self, obj, baseobject, isHole, start, getsim):
        '''_buildPathArea(obj, baseobject, isHole, start, getsim) ... internal function.'''
        # pylint: disable=unused-argument
        PathLog.track()
        area = Path.Area()
        area.setPlane(PathUtils.makeWorkplane(baseobject))
        area.add(baseobject)

        areaParams = self.areaOpAreaParams(obj, isHole)  # pylint: disable=assignment-from-no-return

        heights = [i for i in self.depthparams]
        PathLog.debug('depths: {}'.format(heights))
        area.setParams(**areaParams)
        obj.AreaParams = str(area.getParams())

        PathLog.debug("Area with params: {}".format(area.getParams()))

        sections = area.makeSections(mode=0,
                                     project=self.areaOpUseProjection(obj),
                                     heights=heights)
        PathLog.debug("sections = %s" % sections)
        shapelist = [sec.getShape() for sec in sections]
        PathLog.debug("shapelist = %s" % shapelist)

        pathParams = self.areaOpPathParams(obj, isHole)  # pylint: disable=assignment-from-no-return
        pathParams['shapes'] = shapelist
        pathParams['feedrate'] = self.horizFeed
        pathParams['feedrate_v'] = self.vertFeed
        pathParams['verbose'] = True
        pathParams['resume_height'] = obj.SafeHeight.Value
        pathParams['retraction'] = obj.ClearanceHeight.Value
        pathParams['return_end'] = True
        # Note that emitting preambles between moves breaks some dressups and prevents path optimization on some controllers
        pathParams['preamble'] = False

        if not self.areaOpRetractTool(obj):
            pathParams['threshold'] = 2.001 * self.radius

        if self.endVector is not None:
            pathParams['start'] = self.endVector
        elif PathOp.FeatureStartPoint & self.opFeatures(
                obj) and obj.UseStartPoint:
            pathParams['start'] = obj.StartPoint

        obj.PathParams = str({
            key: value
            for key, value in pathParams.items() if key != 'shapes'
        })
        PathLog.debug("Path with params: {}".format(obj.PathParams))

        (pp, end_vector) = Path.fromShapes(**pathParams)
        PathLog.debug('pp: {}, end vector: {}'.format(pp, end_vector))
        self.endVector = end_vector  # pylint: disable=attribute-defined-outside-init

        simobj = None
        if getsim:
            areaParams['Thicken'] = True
            areaParams['ToolRadius'] = self.radius - self.radius * .005
            area.setParams(**areaParams)
            sec = area.makeSections(mode=0, project=False,
                                    heights=heights)[-1].getShape()
            simobj = sec.extrude(FreeCAD.Vector(0, 0,
                                                baseobject.BoundBox.ZMax))

        return pp, simobj
示例#38
0
    def opExecute(self, obj, getsim=False):  # pylint: disable=arguments-differ
        '''opExecute(obj, getsim=False) ... implementation of Path.Area ops.
        determines the parameters for _buildPathArea().
        Do not overwrite, implement
            areaOpAreaParams(obj, isHole) ... op specific area param dictionary
            areaOpPathParams(obj, isHole) ... op specific path param dictionary
            areaOpShapes(obj)             ... the shape for path area to process
            areaOpUseProjection(obj)      ... return true if operation can use projection
        instead.'''
        PathLog.track()

        # Instantiate class variables for operation reference
        self.endVector = None  # pylint: disable=attribute-defined-outside-init
        self.rotateFlag = False  # pylint: disable=attribute-defined-outside-init
        self.leadIn = 2.0  # pylint: disable=attribute-defined-outside-init
        self.cloneNames = []  # pylint: disable=attribute-defined-outside-init
        self.guiMsgs = []  # pylint: disable=attribute-defined-outside-init
        self.tempObjectNames = []  # pylint: disable=attribute-defined-outside-init
        self.stockBB = PathUtils.findParentJob(obj).Stock.Shape.BoundBox  # pylint: disable=attribute-defined-outside-init
        self.useTempJobClones(
            'Delete')  # Clear temporary group and recreate for temp job clones
        self.profileEdgesIsOpen = False

        if obj.EnableRotation != 'Off':
            # Calculate operation heights based upon rotation radii
            opHeights = self.opDetermineRotationRadii(obj)
            (self.xRotRad, self.yRotRad, self.zRotRad) = opHeights[0]  # pylint: disable=attribute-defined-outside-init
            (self.clrOfset, self.safOfst) = opHeights[1]  # pylint: disable=attribute-defined-outside-init

            # Set clearance and safe heights based upon rotation radii
            if obj.EnableRotation == 'A(x)':
                strDep = self.xRotRad
            elif obj.EnableRotation == 'B(y)':
                strDep = self.yRotRad
            else:
                strDep = max(self.xRotRad, self.yRotRad)
            finDep = -1 * strDep

            obj.ClearanceHeight.Value = strDep + self.clrOfset
            obj.SafeHeight.Value = strDep + self.safOfst

            # Create visual axes when debugging.
            if PathLog.getLevel(PathLog.thisModule()) == 4:
                self.visualAxis()
        else:
            strDep = obj.StartDepth.Value
            finDep = obj.FinalDepth.Value

        # Set axial feed rates based upon horizontal feed rates
        safeCircum = 2 * math.pi * obj.SafeHeight.Value
        self.axialFeed = 360 / safeCircum * self.horizFeed  # pylint: disable=attribute-defined-outside-init
        self.axialRapid = 360 / safeCircum * self.horizRapid  # pylint: disable=attribute-defined-outside-init

        # Initiate depthparams and calculate operation heights for rotational operation
        self.depthparams = self._customDepthParams(obj, obj.StartDepth.Value,
                                                   obj.FinalDepth.Value)

        # Set start point
        if PathOp.FeatureStartPoint & self.opFeatures(
                obj) and obj.UseStartPoint:
            start = obj.StartPoint
        else:
            start = None

        aOS = self.areaOpShapes(obj)  # pylint: disable=assignment-from-no-return

        # Adjust tuples length received from other PathWB tools/operations beside PathPocketShape
        shapes = []
        for shp in aOS:
            if len(shp) == 2:
                (fc, iH) = shp
                #     fc, iH,   sub,   angle, axis,      strtDep,             finDep
                tup = fc, iH, 'otherOp', 0.0, 'S', obj.StartDepth.Value, obj.FinalDepth.Value
                shapes.append(tup)
            else:
                shapes.append(shp)

        if len(shapes) > 1:
            jobs = [{
                'x': s[0].BoundBox.XMax,
                'y': s[0].BoundBox.YMax,
                'shape': s
            } for s in shapes]

            jobs = PathUtils.sort_jobs(jobs, ['x', 'y'])

            shapes = [j['shape'] for j in jobs]

        if self.profileEdgesIsOpen is True:
            if PathOp.FeatureStartPoint & self.opFeatures(
                    obj) and obj.UseStartPoint:
                osp = obj.StartPoint
                self.commandlist.append(
                    Path.Command('G0', {
                        'X': osp.x,
                        'Y': osp.y,
                        'F': self.horizRapid
                    }))

        sims = []
        numShapes = len(shapes)
        for ns in range(0, numShapes):
            (shape, isHole, sub, angle, axis, strDep, finDep) = shapes[ns]  # pylint: disable=unused-variable
            if ns < numShapes - 1:
                nextAxis = shapes[ns + 1][4]
            else:
                nextAxis = 'L'

            self.depthparams = self._customDepthParams(obj, strDep, finDep)

            try:
                if self.profileEdgesIsOpen is True:
                    (pp, sim) = self._buildProfileOpenEdges(
                        obj, shape, isHole, start, getsim)
                else:
                    (pp, sim) = self._buildPathArea(obj, shape, isHole, start,
                                                    getsim)
            except Exception as e:  # pylint: disable=broad-except
                FreeCAD.Console.PrintError(e)
                FreeCAD.Console.PrintError(
                    "Something unexpected happened. Check project and tool config."
                )
            else:
                if self.profileEdgesIsOpen is True:
                    ppCmds = pp
                else:
                    ppCmds = pp.Commands
                if obj.EnableRotation != 'Off' and self.rotateFlag is True:
                    # Rotate model to index for cut
                    if axis == 'X':
                        axisOfRot = 'A'
                    elif axis == 'Y':
                        axisOfRot = 'B'
                    elif axis == 'Z':
                        axisOfRot = 'C'
                    else:
                        axisOfRot = 'A'
                    # Rotate Model to correct angle
                    ppCmds.insert(
                        0,
                        Path.Command('G0', {
                            axisOfRot: angle,
                            'F': self.axialRapid
                        }))

                    # Raise cutter to safe height
                    ppCmds.insert(
                        0,
                        Path.Command('G0', {
                            'Z': obj.SafeHeight.Value,
                            'F': self.vertRapid
                        }))

                    # Return index to starting position if axis of rotation changes.
                    if numShapes > 1:
                        if ns != numShapes - 1:
                            if axis != nextAxis:
                                ppCmds.append(
                                    Path.Command('G0', {
                                        axisOfRot: 0.0,
                                        'F': self.axialRapid
                                    }))
                # Eif

                # Save gcode commands to object command list
                self.commandlist.extend(ppCmds)
                sims.append(sim)
            # Eif

            if self.areaOpRetractTool(obj):
                self.endVector = None  # pylint: disable=attribute-defined-outside-init

        # Raise cutter to safe height and rotate back to original orientation
        if self.rotateFlag is True:
            resetAxis = False
            lastJobOp = None
            nextJobOp = None
            opIdx = 0
            JOB = PathUtils.findParentJob(obj)
            jobOps = JOB.Operations.Group
            numJobOps = len(jobOps)

            for joi in range(0, numJobOps):
                jo = jobOps[joi]
                if jo.Name == obj.Name:
                    opIdx = joi
            lastOpIdx = opIdx - 1
            nextOpIdx = opIdx + 1
            if lastOpIdx > -1:
                lastJobOp = jobOps[lastOpIdx]
            if nextOpIdx < numJobOps:
                nextJobOp = jobOps[nextOpIdx]

            if lastJobOp is not None:
                if hasattr(lastJobOp, 'EnableRotation'):
                    PathLog.debug(
                        'Last Op, {}, has `EnableRotation` set to {}'.format(
                            lastJobOp.Label, lastJobOp.EnableRotation))
                    if lastJobOp.EnableRotation != obj.EnableRotation:
                        resetAxis = True
            if ns == numShapes - 1:  # If last shape, check next op EnableRotation setting
                if nextJobOp is not None:
                    if hasattr(nextJobOp, 'EnableRotation'):
                        PathLog.debug(
                            'Next Op, {}, has `EnableRotation` set to {}'.
                            format(nextJobOp.Label, nextJobOp.EnableRotation))
                        if nextJobOp.EnableRotation != obj.EnableRotation:
                            resetAxis = True

            # Raise to safe height if rotation activated
            self.commandlist.append(
                Path.Command('G0', {
                    'Z': obj.SafeHeight.Value,
                    'F': self.vertRapid
                }))
            # reset rotational axes if necessary
            if resetAxis is True:
                self.commandlist.append(
                    Path.Command('G0', {
                        'A': 0.0,
                        'F': self.axialRapid
                    }))
                self.commandlist.append(
                    Path.Command('G0', {
                        'B': 0.0,
                        'F': self.axialRapid
                    }))

        self.useTempJobClones(
            'Delete')  # Delete temp job clone group and contents
        self.guiMessage('title', None,
                        show=True)  # Process GUI messages to user
        for ton in self.tempObjectNames:  # remove temporary objects by name
            FreeCAD.ActiveDocument.removeObject(ton)
        PathLog.debug("obj.Name: " + str(obj.Name) + "\n\n")
        return sims
示例#39
0
 def test10(self):
     """Verify proper geometry objects for G1 and G01 commands are created."""
     spt = Vector(1,2,3)
     self.assertLine(PathGeom.edgeForCmd(Path.Command('G1',  {'X': 7, 'Y': 2, 'Z': 3}), spt), spt, Vector(7, 2, 3))
     self.assertLine(PathGeom.edgeForCmd(Path.Command('G01', {'X': 1, 'Y': 3, 'Z': 5}), spt), spt, Vector(1, 3, 5))
示例#40
0
    def createPath(self, obj, pathData, tags):
        PathLog.track()
        commands = []
        lastEdge = 0
        lastTag = 0
        sameTag = None
        t = 0
        inters = None
        edge = None

        segm = 50
        if hasattr(obj, 'SegmentationFactor'):
            segm = obj.SegmentationFactor
            if segm <= 0:
                segm = 50
                obj.SegmentationFactor = 50

        self.mappers = []
        mapper = None

        while edge or lastEdge < len(pathData.edges):
            PathLog.debug("------- lastEdge = %d/%d.%d/%d" %
                          (lastEdge, lastTag, t, len(tags)))
            if not edge:
                edge = pathData.edges[lastEdge]
                debugEdge(
                    edge, "=======  new edge: %d/%d" %
                    (lastEdge, len(pathData.edges)))
                lastEdge += 1
                sameTag = None

            if mapper:
                mapper.add(edge)
                if mapper.mappingComplete():
                    commands.extend(mapper.commands)
                    edge = mapper.tail
                    mapper = None
                else:
                    edge = None

            if edge:
                tIndex = (t + lastTag) % len(tags)
                t += 1
                i = tags[tIndex].intersects(edge, edge.FirstParameter)
                if i and self.isValidTagStartIntersection(edge, i):
                    mapper = MapWireToTag(edge, tags[tIndex], i, segm,
                                          pathData.maxZ)
                    self.mappers.append(mapper)
                    edge = mapper.tail

            if not mapper and t >= len(tags):
                # gone through all tags, consume edge and move on
                if edge:
                    debugEdge(edge, '++++++++')
                    if pathData.rapid.isRapid(edge):
                        v = edge.Vertexes[1]
                        commands.append(
                            Path.Command('G0', {
                                'X': v.X,
                                'Y': v.Y,
                                'Z': v.Z
                            }))
                    else:
                        commands.extend(PathGeom.cmdsForEdge(edge, segm=segm))
                edge = None
                t = 0

        lastCmd = Path.Command('G0', {
            'X': 0.0,
            'Y': 0.0,
            'Z': 0.0
        })
        outCommands = []

        horizFeed = obj.Base.ToolController.HorizFeed.Value
        vertFeed = obj.Base.ToolController.VertFeed.Value
        horizRapid = obj.Base.ToolController.HorizRapid.Value
        vertRapid = obj.Base.ToolController.VertRapid.Value

        for cmd in commands:
            params = cmd.Parameters
            zVal = params.get('Z', None)
            zVal2 = lastCmd.Parameters.get('Z', None)

            zVal = zVal and round(zVal, 8)
            zVal2 = zVal2 and round(zVal2, 8)

            if cmd.Name in ['G1', 'G2', 'G3', 'G01', 'G02', 'G03']:
                if zVal is not None and zVal2 != zVal:
                    params['F'] = vertFeed
                else:
                    params['F'] = horizFeed
                lastCmd = cmd

            elif cmd.Name in ['G0', 'G00']:
                if zVal is not None and zVal2 != zVal:
                    params['F'] = vertRapid
                else:
                    params['F'] = horizRapid
                lastCmd = cmd

            outCommands.append(Path.Command(cmd.Name, params))

        return Path.Path(outCommands)
示例#41
0
def GenerateGCode(op, obj, adaptiveResults, helixDiameter):
    if len(adaptiveResults) == 0 or len(
            adaptiveResults[0]["AdaptivePaths"]) == 0:
        return

    minLiftDistance = op.tool.Diameter
    helixRadius = 0
    for region in adaptiveResults:
        p1 = region["HelixCenterPoint"]
        p2 = region["StartPoint"]
        r = math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) *
                      (p1[1] - p2[1]))
        if r > helixRadius:
            helixRadius = r

    stepDown = obj.StepDown.Value
    passStartDepth = obj.StartDepth.Value

    if stepDown < 0.1:
        stepDown = 0.1

    length = 2 * math.pi * helixRadius

    if float(obj.HelixAngle) < 1:
        obj.HelixAngle = 1

    helixAngleRad = math.pi * float(obj.HelixAngle) / 180.0
    depthPerOneCircle = length * math.tan(helixAngleRad)
    #print("Helix circle depth: {}".format(depthPerOneCircle))

    stepUp = obj.LiftDistance.Value
    if stepUp < 0:
        stepUp = 0

    finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0
    if finish_step > stepDown:
        finish_step = stepDown

    depth_params = PathUtils.depth_params(
        clearance_height=obj.ClearanceHeight.Value,
        safe_height=obj.SafeHeight.Value,
        start_depth=obj.StartDepth.Value,
        step_down=stepDown,
        z_finish_step=finish_step,
        final_depth=obj.FinalDepth.Value,
        user_depths=None)

    lx = adaptiveResults[0]["HelixCenterPoint"][0]
    ly = adaptiveResults[0]["HelixCenterPoint"][1]
    lz = passStartDepth
    step = 0

    for passEndDepth in depth_params.data:
        step = step + 1

        for region in adaptiveResults:
            startAngle = math.atan2(
                region["StartPoint"][1] - region["HelixCenterPoint"][1],
                region["StartPoint"][0] - region["HelixCenterPoint"][0])

            lx = region["HelixCenterPoint"][0]
            ly = region["HelixCenterPoint"][1]

            passDepth = (passStartDepth - passEndDepth)

            p1 = region["HelixCenterPoint"]
            p2 = region["StartPoint"]
            helixRadius = math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) +
                                    (p1[1] - p2[1]) * (p1[1] - p2[1]))

            # helix ramp
            if helixRadius > 0.001:
                r = helixRadius - 0.01

                maxfi = passDepth / depthPerOneCircle * 2 * math.pi
                fi = 0
                offsetFi = -maxfi + startAngle - math.pi / 16

                helixStart = [
                    region["HelixCenterPoint"][0] + r * math.cos(offsetFi),
                    region["HelixCenterPoint"][1] + r * math.sin(offsetFi)
                ]

                op.commandlist.append(
                    Path.Command("(Helix to depth: %f)" % passEndDepth))

                if obj.UseHelixArcs == False:
                    # rapid move to start point
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.ClearanceHeight.Value
                            }))

                    # rapid move to safe height
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.SafeHeight.Value
                            }))

                    # move to start depth
                    op.commandlist.append(
                        Path.Command(
                            "G1", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": passStartDepth,
                                "F": op.vertFeed
                            }))

                    while fi < maxfi:
                        x = region["HelixCenterPoint"][0] + r * math.cos(
                            fi + offsetFi)
                        y = region["HelixCenterPoint"][1] + r * math.sin(
                            fi + offsetFi)
                        z = passStartDepth - fi / maxfi * (passStartDepth -
                                                           passEndDepth)
                        op.commandlist.append(
                            Path.Command("G1", {
                                "X": x,
                                "Y": y,
                                "Z": z,
                                "F": op.vertFeed
                            }))
                        lx = x
                        ly = y
                        fi = fi + math.pi / 16

                    # one more circle at target depth to make sure center is cleared
                    maxfi = maxfi + 2 * math.pi
                    while fi < maxfi:
                        x = region["HelixCenterPoint"][0] + r * math.cos(
                            fi + offsetFi)
                        y = region["HelixCenterPoint"][1] + r * math.sin(
                            fi + offsetFi)
                        z = passEndDepth
                        op.commandlist.append(
                            Path.Command("G1", {
                                "X": x,
                                "Y": y,
                                "Z": z,
                                "F": op.horizFeed
                            }))
                        lx = x
                        ly = y
                        fi = fi + math.pi / 16
                else:
                    helixStart = [
                        region["HelixCenterPoint"][0] + r,
                        region["HelixCenterPoint"][1]
                    ]

                    # rapid move to start point
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.ClearanceHeight.Value
                            }))

                    # rapid move to safe height
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.SafeHeight.Value
                            }))

                    # move to start depth
                    op.commandlist.append(
                        Path.Command(
                            "G1", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": passStartDepth,
                                "F": op.vertFeed
                            }))

                    x = region["HelixCenterPoint"][0] + r
                    y = region["HelixCenterPoint"][1]

                    curDep = passStartDepth
                    while curDep > (passEndDepth + depthPerOneCircle):
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x - (2 * r),
                                    "Y": y,
                                    "Z": curDep - (depthPerOneCircle / 2),
                                    "I": -r,
                                    "F": op.horizFeed
                                }))
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x,
                                    "Y": y,
                                    "Z": curDep - depthPerOneCircle,
                                    "I": r,
                                    "F": op.horizFeed
                                }))
                        curDep = curDep - depthPerOneCircle

                    lastStep = curDep - passEndDepth
                    if lastStep > (depthPerOneCircle / 2):
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x - (2 * r),
                                    "Y": y,
                                    "Z": curDep - (lastStep / 2),
                                    "I": -r,
                                    "F": op.horizFeed
                                }))
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x,
                                    "Y": y,
                                    "Z": passEndDepth,
                                    "I": r,
                                    "F": op.horizFeed
                                }))
                    else:
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x - (2 * r),
                                    "Y": y,
                                    "Z": passEndDepth,
                                    "I": -r,
                                    "F": op.horizFeed
                                }))
                        op.commandlist.append(
                            Path.Command(
                                "G1", {
                                    "X": x,
                                    "Y": y,
                                    "Z": passEndDepth,
                                    "F": op.vertFeed
                                }))

                    # one more circle at target depth to make sure center is cleared
                    op.commandlist.append(
                        Path.Command(
                            "G2", {
                                "X": x - (2 * r),
                                "Y": y,
                                "Z": passEndDepth,
                                "I": -r,
                                "F": op.horizFeed
                            }))
                    op.commandlist.append(
                        Path.Command(
                            "G2", {
                                "X": x,
                                "Y": y,
                                "Z": passEndDepth,
                                "I": r,
                                "F": op.horizFeed
                            }))
                    lx = x
                    ly = y

            else:  # no helix entry
                # rapid move to clearance height
                op.commandlist.append(
                    Path.Command(
                        "G0", {
                            "X": region["StartPoint"][0],
                            "Y": region["StartPoint"][1],
                            "Z": obj.ClearanceHeight.Value
                        }))
                # straight plunge to target depth
                op.commandlist.append(
                    Path.Command(
                        "G1", {
                            "X": region["StartPoint"][0],
                            "Y": region["StartPoint"][1],
                            "Z": passEndDepth,
                            "F": op.vertFeed
                        }))

            lz = passEndDepth
            z = obj.ClearanceHeight.Value
            op.commandlist.append(
                Path.Command("(Adaptive - depth: %f)" % passEndDepth))

            # add adaptive paths
            for pth in region["AdaptivePaths"]:
                motionType = pth[0]  #[0] contains motion type

                for pt in pth[1]:  #[1] contains list of points
                    x = pt[0]
                    y = pt[1]

                    dist = math.sqrt((x - lx) * (x - lx) + (y - ly) * (y - ly))

                    if motionType == area.AdaptiveMotionType.Cutting:
                        z = passEndDepth
                        if z != lz:
                            op.commandlist.append(
                                Path.Command("G1", {
                                    "Z": z,
                                    "F": op.vertFeed
                                }))

                        op.commandlist.append(
                            Path.Command("G1", {
                                "X": x,
                                "Y": y,
                                "F": op.horizFeed
                            }))

                    elif motionType == area.AdaptiveMotionType.LinkClear:
                        z = passEndDepth + stepUp
                        if z != lz:
                            op.commandlist.append(Path.Command("G0", {"Z": z}))

                        op.commandlist.append(
                            Path.Command("G0", {
                                "X": x,
                                "Y": y
                            }))

                    elif motionType == area.AdaptiveMotionType.LinkNotClear:
                        z = obj.ClearanceHeight.Value
                        if z != lz:
                            op.commandlist.append(Path.Command("G0", {"Z": z}))

                        op.commandlist.append(
                            Path.Command("G0", {
                                "X": x,
                                "Y": y
                            }))

                    # elif motionType == area.AdaptiveMotionType.LinkClearAtPrevPass:
                    #     if lx!=x or ly!=y:
                    #         op.commandlist.append(Path.Command("G0", { "X": lx, "Y":ly, "Z":passStartDepth+stepUp}))
                    #     op.commandlist.append(Path.Command("G0", { "X": x, "Y":y, "Z":passStartDepth+stepUp}))

                    lx = x
                    ly = y
                    lz = z

            # return to safe height in this Z pass
            z = obj.ClearanceHeight.Value
            if z != lz:
                op.commandlist.append(Path.Command("G0", {"Z": z}))

            lz = z

        passStartDepth = passEndDepth

        # return to safe height in this Z pass
        z = obj.ClearanceHeight.Value
        if z != lz:
            op.commandlist.append(Path.Command("G0", {"Z": z}))

        lz = z

    z = obj.ClearanceHeight.Value
    if z != lz:
        op.commandlist.append(Path.Command("G0", {"Z": z}))

    lz = z
示例#42
0
    def PerformCutVoxel(self):
        if self.resetSimulation:
            self.resetSimulation = False
            self.SetupSimulation()

        if self.busy:
            return
        self.busy = True

        cmd = self.opCommands[self.icmd]
        # for cmd in job.Path.Commands:
        if cmd.Name in ["G0", "G1", "G2", "G3"]:
            self.firstDrill = True
            if cmd.Name in ["G2", "G3"] and (cmd.k or 0) == 0:
                cx = self.curpos.Base.x + (cmd.i or 0)
                cy = self.curpos.Base.y + (cmd.j or 0)
                a0 = math.atan2(self.curpos.Base.y - cy,
                                self.curpos.Base.x - cx)
                a1 = math.atan2(cmd.y - cy, cmd.x - cx)
                da = a1 - a0
                if cmd.Name == "G3":
                    da = da % (2 * math.pi)
                else:
                    da = -((-da) % (2 * math.pi))
                r = math.sqrt((cmd.i or 0)**2 + (cmd.j or 0)**2)
                n = math.ceil(math.sqrt(r / self.resolution * da * da))
                da = da / n
                dz = (cmd.z - self.curpos.Base.z) / n
                cmd.Name = "G1"
                for i in range(n):
                    a0 += da
                    cmd.x = cx + r * math.cos(a0)
                    cmd.y = cy + r * math.sin(a0)
                    cmd.z = self.curpos.Base.z + dz
                    self.curpos = self.voxSim.ApplyCommand(self.curpos, cmd)
            else:
                self.curpos = self.voxSim.ApplyCommand(self.curpos, cmd)
            if not self.disableAnim:
                self.cutTool.Placement = self.curpos
                (
                    self.cutMaterial.Mesh,
                    self.cutMaterialIn.Mesh,
                ) = self.voxSim.GetResultMesh()
        if cmd.Name in ["G80"]:
            self.firstDrill = True
        if cmd.Name in ["G73", "G81", "G82", "G83"]:
            extendcommands = []
            if self.firstDrill:
                extendcommands.append(Path.Command("G0", {"Z": cmd.r}))
                self.firstDrill = False
            extendcommands.append(
                Path.Command("G0", {
                    "X": cmd.x,
                    "Y": cmd.y,
                    "Z": cmd.r
                }))
            extendcommands.append(
                Path.Command("G1", {
                    "X": cmd.x,
                    "Y": cmd.y,
                    "Z": cmd.z
                }))
            extendcommands.append(
                Path.Command("G1", {
                    "X": cmd.x,
                    "Y": cmd.y,
                    "Z": cmd.r
                }))
            for ecmd in extendcommands:
                self.curpos = self.voxSim.ApplyCommand(self.curpos, ecmd)
                if not self.disableAnim:
                    self.cutTool.Placement = self.curpos
                    (
                        self.cutMaterial.Mesh,
                        self.cutMaterialIn.Mesh,
                    ) = self.voxSim.GetResultMesh()
        self.icmd += 1
        self.iprogress += 1
        self.UpdateProgress()
        if self.icmd >= len(self.opCommands):
            self.ioperation += 1
            if self.ioperation >= len(self.activeOps):
                self.EndSimulation()
                return
            else:
                self.SetupOperation(self.ioperation)
        self.busy = False
示例#43
0
 def execute(self, obj):
     output = ""
     output += '(' + str(obj.Comment) + ')\n'
     path = Path.Path(output)
     obj.Path = path
示例#44
0
    def buildPathMedial(self, obj, faces):
        '''constructs a medial axis path using openvoronoi'''

        def insert_many_wires(vd, wires):
            for wire in wires:
                PathLog.debug('discretize value: {}'.format(obj.Discretize))
                pts = wire.discretize(QuasiDeflection=obj.Discretize)
                ptv = [FreeCAD.Vector(p.x, p.y) for p in pts]
                ptv.append(ptv[0])

                for i in range(len(pts)):
                    vd.addSegment(ptv[i], ptv[i+1])

        def cutWire(edges):
            path = []
            path.append(Path.Command("G0 Z{}".format(obj.SafeHeight.Value)))
            e = edges[0]
            p = e.valueAt(e.FirstParameter)
            path.append(Path.Command("G0 X{} Y{} Z{}".format(p.x, p.y, obj.SafeHeight.Value)))
            hSpeed = obj.ToolController.HorizFeed.Value
            vSpeed = obj.ToolController.VertFeed.Value
            path.append(Path.Command("G1 X{} Y{} Z{} F{}".format(p.x, p.y, p.z, vSpeed)))
            for e in edges:
                path.extend(PathGeom.cmdsForEdge(e, hSpeed=hSpeed, vSpeed=vSpeed))

            return path

        VD.clear()
        voronoiWires = []
        for f in faces:
            vd = Path.Voronoi()
            insert_many_wires(vd, f.Wires)

            vd.construct()

            for e in vd.Edges:
                e.Color = PRIMARY if e.isPrimary() else SECONDARY
            vd.colorExterior(EXTERIOR1)
            vd.colorExterior(EXTERIOR2,
                lambda v: not f.isInside(v.toPoint(f.BoundBox.ZMin),
                obj.Tolerance, True))
            vd.colorColinear(COLINEAR, obj.Colinear)
            vd.colorTwins(TWIN)

            wires = _collectVoronoiWires(vd)
            if _sorting != 'global':
                wires = _sortVoronoiWires(wires)
            voronoiWires.extend(wires)
            VD.append((f, vd, wires))

        if _sorting == 'global':
            voronoiWires = _sortVoronoiWires(voronoiWires)

        geom = _Geometry.FromObj(obj, self.model[0])

        pathlist = []
        pathlist.append(Path.Command("(starting)"))
        for w in voronoiWires:
            pWire = self._getPartEdges(obj, w, geom)
            if pWire:
                wires.append(pWire)
                pathlist.extend(cutWire(pWire))
        self.commandlist = pathlist
示例#45
0
def extract(base_date):
    pkl_path = Path.of_cache('time_related.%s.pkl' % base_date)
    X = IO.fetch_cache(pkl_path)
    if X is not None:
        logger.debug('cache hit')
        return X

    logger.debug('cache missed')
    logger.debug('prepare datasets ...')

    enroll_all = IO.load_enrollments()
    log_all = IO.load_logs()
    obj_all = IO.load_object()

    log_all = log_all[log_all['time'] <= base_date]
    obj_all = obj_all[obj_all['start'] <= base_date]

    logger.debug('datasets prepared')

    CT = course_duration(log_all, obj_all, enroll_all)

    # 0~1: 课程材料首次发布、最近发布距今几天
    XC = CT.copy()
    XC['st'] = (base_date - XC['st']).dt.days
    XC['et'] = (base_date - XC['et']).dt.days

    logger.debug('0~1')

    ET = log_all.groupby('enrollment_id').agg({'time': [np.min, np.max]})
    ET.columns = ['st_e', 'et_e']
    ET.reset_index(inplace=True)
    ET['duration'] = (ET['et_e'] - ET['st_e']).dt.days
    ET = pd.merge(ET, enroll_all, how='left', on='enrollment_id')
    ET = pd.merge(ET, CT, how='left', on='course_id')
    ET['duration_ratio'] = (ET['et'] - ET['st']).dt.days
    ET['duration_ratio'] = ET['duration'] / ET['duration_ratio']
    ET['first_op'] = (ET['st_e'] - ET['st']).dt.days
    ET['first_month'] = ET['st_e'].dt.month
    ET['last_month'] = ET['et_e'].dt.month
    UT = ET.copy()
    del ET['st']
    del ET['et']
    del ET['username']
    del ET['course_id']

    # 2~6: 用户初次、上次操作此课程据今几天,持续几天,与课程持续时间的比例,
    # 初次访问课程材料距离开课时间几天
    # 15~16: month (1-12) of the first, last event in the enrollment
    XE = ET.copy()
    XE['st_e'] = (base_date - XE['st_e']).dt.days
    XE['et_e'] = (base_date - XE['et_e']).dt.days

    logger.debug('2~6, 15~16')

    # 7~14: 课程的所有用户操作课程持续时间的:平均值、标准差、最大值、最小值,
    # 以及与课程持续时间的比例
    XU = UT.groupby('course_id').agg({
            'duration': [np.average, np.std, np.max, np.min],
            'duration_ratio': [np.average, np.std, np.max, np.min]
            }).reset_index()
    XU.columns = [' '.join(c).strip() for c in XU.columns.values]

    logger.debug('7~14')

    op_time = log_all.groupby(['enrollment_id', 'object'])\
        .agg({'time': np.min}).reset_index()
    op_time = pd.merge(op_time, enroll_all, how='left', on='enrollment_id')
    op_time = pd.merge(op_time,
                       obj_all.rename(columns={'module_id': 'object'}),
                       how='left', on=['course_id', 'object'])

    first_op_time = pd.merge(log_all, enroll_all, how='left',
                             on='enrollment_id')\
        .groupby(['course_id', 'object']).agg({'time': np.min}).reset_index()
    first_op_time.rename(columns={'time': 'first_op_time'}, inplace=True)

    op_time = pd.merge(op_time, first_op_time, how='left',
                       on=['course_id', 'object'])
    op_time.ix[pd.isnull(op_time['start']), 'start'] = \
        op_time.ix[pd.isnull(op_time['start']), 'first_op_time']

    op_time['delay'] = (op_time['time'] - op_time['start']).dt.days
    import events
    op_time = pd.merge(op_time, events.enroll_duration(log_all), how='left',
                       on='enrollment_id')

    op_last_week = op_time[
        op_time['time'] > op_time['et'] - timedelta(days=7)].copy()
    op_2nd_last_week = op_time[
        (op_time['time'] > op_time['et'] - timedelta(days=14)) &
        (op_time['time'] <= op_time['et'] - timedelta(days=7))].copy()
    op_first_week = op_time[
        op_time['time'] < op_time['st'] + timedelta(days=7)].copy()

    # 17~32: 用户对课程材料的首次操作时间与课程材料发布时间的日期差的:
    # 平均值、标准差、最大值、最小值,enrollment最后一周、倒数第二周、第一周、总体
    XO_last_week = op_last_week.groupby('enrollment_id')\
        .agg({'delay': [np.average, np.std, np.max, np.min]})\
        .reset_index()
    XO_last_week.columns = [' '.join(c).strip()
                            for c in XO_last_week.columns.values]
    XO_2nd_last_week = op_2nd_last_week.groupby('enrollment_id')\
        .agg({'delay': [np.average, np.std, np.max, np.min]})\
        .reset_index()
    XO_2nd_last_week.columns = [' '.join(c).strip()
                                for c in XO_2nd_last_week.columns.values]
    XO_first_week = op_first_week.groupby('enrollment_id')\
        .agg({'delay': [np.average, np.std, np.max, np.min]})\
        .reset_index()
    XO_first_week.columns = [' '.join(c).strip()
                             for c in XO_first_week.columns.values]
    XO_all = op_time.groupby('enrollment_id')\
        .agg({'delay': [np.average, np.std, np.max, np.min]})\
        .reset_index()
    XO_all.columns = [' '.join(c).strip() for c in XO_all.columns.values]

    logger.debug('17~32')

    check_dataframe = Util.dataframe_checker(logger)

    check_dataframe(XC, 'XC')
    X = pd.merge(enroll_all, XC, how='left', on='course_id')

    check_dataframe(XE, 'XE')
    X = pd.merge(X, XE, how='left', on='enrollment_id')

    check_dataframe(XU, 'XU')
    X = pd.merge(X, XU, how='left', on='course_id')

    check_dataframe(XO_last_week, 'XO_last_week')
    X = pd.merge(X, XO_last_week, how='left', on='enrollment_id')

    check_dataframe(XO_2nd_last_week, 'XO_2nd_last_week')
    X = pd.merge(X, XO_2nd_last_week, how='left', on='enrollment_id')

    check_dataframe(XO_first_week, 'XO_first_week')
    X = pd.merge(X, XO_first_week, how='left', on='enrollment_id')

    check_dataframe(XO_all, 'XO_all')
    X = pd.merge(X, XO_all, how='left', on='enrollment_id')

    del X['username']
    del X['course_id']

    X.fillna(0, inplace=True)
    check_dataframe(X, 'X')
    IO.cache(X, pkl_path)

    return X
示例#46
0
def buildPostList(job):
    """Takes the job and determines the specific objects and order to
    postprocess  Returns a list of objects which can be passed to
    exportObjectsWith() for final posting"""
    wcslist = job.Fixtures
    orderby = job.OrderOutputBy

    postlist = []

    if orderby == "Fixture":
        PathLog.debug("Ordering by Fixture")
        # Order by fixture means all operations and tool changes will be completed in one
        # fixture before moving to the next.

        currTool = None
        for index, f in enumerate(wcslist):
            # create an object to serve as the fixture path
            fobj = _TempObject()
            c1 = Path.Command(f)
            fobj.Path = Path.Path([c1])
            if index != 0:
                c2 = Path.Command(
                    "G0 Z"
                    + str(
                        job.Stock.Shape.BoundBox.ZMax
                        + job.SetupSheet.ClearanceHeightOffset.Value
                    )
                )
                fobj.Path.addCommands(c2)
            fobj.InList.append(job)
            sublist = [fobj]

            # Now generate the gcode
            for obj in job.Operations.Group:
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None and PathUtil.opProperty(obj, "Active"):
                    if tc.ToolNumber != currTool:
                        sublist.append(tc)
                        PathLog.debug("Appending TC: {}".format(tc.Name))
                        currTool = tc.ToolNumber
                sublist.append(obj)
            postlist.append((f, sublist))

    elif orderby == "Tool":
        PathLog.debug("Ordering by Tool")
        # Order by tool means tool changes are minimized.
        # all operations with the current tool are processed in the current
        # fixture before moving to the next fixture.

        toolstring = "None"
        currTool = None

        # Build the fixture list
        fixturelist = []
        for f in wcslist:
            # create an object to serve as the fixture path
            fobj = _TempObject()
            c1 = Path.Command(f)
            c2 = Path.Command(
                "G0 Z"
                + str(
                    job.Stock.Shape.BoundBox.ZMax
                    + job.SetupSheet.ClearanceHeightOffset.Value
                )
            )
            fobj.Path = Path.Path([c1, c2])
            fobj.InList.append(job)
            fixturelist.append(fobj)

        # Now generate the gcode
        curlist = []  # list of ops for tool, will repeat for each fixture
        sublist = []  # list of ops for output splitting

        PathLog.track(job.PostProcessorOutputFile)
        for idx, obj in enumerate(job.Operations.Group):
            PathLog.track(obj.Label)

            # check if the operation is active
            if not getattr(obj, "Active", True):
                PathLog.track()
                continue

            # Determine the proper string for the Op's TC
            tc = PathUtil.toolControllerForOp(obj)
            if tc is None:
                tcstring = "None"
            elif "%T" in job.PostProcessorOutputFile:
                tcstring = f"{tc.ToolNumber}"
            else:
                tcstring = re.sub(r"[^\w\d-]", "_", tc.Label)
            PathLog.track(toolstring)

            if tc is None or tc.ToolNumber == currTool:
                curlist.append(obj)
            elif tc.ToolNumber != currTool and currTool is None:  # first TC
                sublist.append(tc)
                curlist.append(obj)
                currTool = tc.ToolNumber
                toolstring = tcstring

            elif tc.ToolNumber != currTool and currTool is not None:  # TC
                for fixture in fixturelist:
                    sublist.append(fixture)
                    sublist.extend(curlist)
                postlist.append((toolstring, sublist))
                sublist = [tc]
                curlist = [obj]
                currTool = tc.ToolNumber
                toolstring = tcstring

            if idx == len(job.Operations.Group) - 1:  # Last operation.
                for fixture in fixturelist:
                    sublist.append(fixture)
                    sublist.extend(curlist)

                postlist.append((toolstring, sublist))

    elif orderby == "Operation":
        PathLog.debug("Ordering by Operation")
        # Order by operation means ops are done in each fixture in
        # sequence.
        currTool = None
        firstFixture = True

        # Now generate the gcode
        for obj in job.Operations.Group:

            # check if the operation is active
            if not getattr(obj, "Active", True):
                continue

            sublist = []
            PathLog.debug("obj: {}".format(obj.Name))

            for f in wcslist:
                fobj = _TempObject()
                c1 = Path.Command(f)
                fobj.Path = Path.Path([c1])
                if not firstFixture:
                    c2 = Path.Command(
                        "G0 Z"
                        + str(
                            job.Stock.Shape.BoundBox.ZMax
                            + job.SetupSheet.ClearanceHeightOffset.Value
                        )
                    )
                    fobj.Path.addCommands(c2)
                fobj.InList.append(job)
                sublist.append(fobj)
                firstFixture = False
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None:
                    if job.SplitOutput or (tc.ToolNumber != currTool):
                        sublist.append(tc)
                        currTool = tc.ToolNumber
                sublist.append(obj)
            postlist.append((obj.Label, sublist))

    if job.SplitOutput:
        PathLog.track()
        return postlist
    else:
        PathLog.track()
        finalpostlist = [
            ("allitems", [item for slist in postlist for item in slist[1]])
        ]
        return finalpostlist
示例#47
0
    def execute(self, obj):
        newpath = []
        global currLocation

        if not obj.Base:
            return

        if not obj.Base.isDerivedFrom("Path::Feature"):
            return

        if obj.Base.Path.Commands:

            firstmove = Path.Command("G0", {"X": 0, "Y": 0, "Z": 0})
            currLocation.update(firstmove.Parameters)

            queue = []

            for curCommand in obj.Base.Path.Commands:
                replace = None
                # don't worry about non-move commands, just add to output
                if curCommand.Name not in movecommands + rapidcommands:
                    newpath.append(curCommand)
                    continue

                # rapid retract triggers exit move, else just add to output
                if curCommand.Name in rapidcommands:
                    if (curCommand.z > obj.pivotheight) and (len(queue) == 3):
                        # Process the exit move
                        tempqueue = queue
                        tempqueue.insert(0, curCommand)

                        if queue[1].Name in ['G01', 'G1']:
                            temp = self.lineExtension(obj, tempqueue)
                            newpath.extend(temp[0])
                            lastxy = temp[0][-1].Placement.Base
                        elif queue[1].Name in arccommands:
                            temp = self.arcExtension(obj, tempqueue)
                            newpath.extend(temp[0])
                            lastxy = temp[0][-1].Placement.Base

                    newpath.append(curCommand)
                    currLocation.update(curCommand.Parameters)
                    queue = []
                    continue

                # keep a queue of feed moves and check for needed corners
                if curCommand.Name in movecommands:
                    changedXYFlag = False
                    if queue:
                        if (curCommand.x != queue[0].x) or (curCommand.y !=
                                                            queue[0].y):
                            queue.insert(0, curCommand)
                            if len(queue) > 3:
                                queue.pop()
                            changedXYFlag = True
                    else:
                        queue = [curCommand]

                    # vertical feeding to depth
                    if curCommand.z != currLocation["Z"]:
                        newpath.append(curCommand)
                        currLocation.update(curCommand.Parameters)
                        continue

                    # Corner possibly needed
                    if changedXYFlag and (len(queue) == 3):

                        # check if the inciden angle incident exceeds the filter
                        incident_angle = self.getIncidentAngle(queue)

                        if abs(incident_angle) >= obj.filterangle:
                            if self.shortcut(queue) == "CW":
                                #if incident_angle >= 0:
                                twistCW = True
                            else:
                                twistCW = False
                            #
                            #  DO THE EXTENSION
                            #
                            if queue[1].Name in ['G01', 'G1']:
                                temp = self.lineExtension(obj, queue)
                                newpath.extend(temp[0])
                                replace = temp[1]
                                lastxy = temp[0][-1].Placement.Base
                            elif queue[1].Name in arccommands:
                                temp = self.arcExtension(obj, queue)
                                newpath.extend(temp[0])
                                replace = temp[1]
                                lastxy = temp[0][-1].Placement.Base
                            else:
                                FreeCAD.Console.PrintWarning(
                                    "I don't know what's up")
                            #
                            #  DO THE TWIST
                            #
                            if queue[0].Name in ['G01', 'G1']:
                                temp = self.lineTwist(obj, queue, lastxy,
                                                      twistCW)
                                replace = temp[1]
                                newpath.extend(temp[0])
                            elif queue[0].Name in arccommands:
                                temp = self.arcTwist(obj, queue, lastxy,
                                                     twistCW)
                                replace = temp[1]
                                newpath.extend(temp[0])
                            else:
                                FreeCAD.Console.PrintWarning(
                                    "I don't know what's up")
                    if replace is None:
                        newpath.append(curCommand)
                    else:
                        newpath.append(replace)
                    currLocation.update(curCommand.Parameters)
                    continue

            commands = newpath
            path = Path.Path(commands)
            obj.Path = path
示例#48
0
def parse(pathobj):
    out = ""
    lastcommand = None
    precision_string = "." + str(PRECISION) + "f"
    currLocation = {}  # keep track for no doubles

    # The params list control the order of parameters
    params = [
        "X",
        "Y",
        "Z",
        "A",
        "B",
        "C",
        "I",
        "J",
        "K",
        "R",
        "F",
        "S",
        "T",
        "H",
        "L",
        "Q",
    ]
    firstmove = Path.Command("G0", {"X": -1, "Y": -1, "Z": -1, "F": 0.0})
    currLocation.update(firstmove.Parameters)  # set First location Parameters

    if hasattr(pathobj, "Group"):
        # We have a compound or project.

        # if OUTPUT_COMMENTS:
        #    out += linenumber() + "(compound: " + pathobj.Label + ")\n"
        for p in pathobj.Group:
            out += parse(p)
        return out
    else:
        # parsing simple path

        # groups might contain non-path things like stock.
        if not hasattr(pathobj, "Path"):
            return out

        # if OUTPUT_COMMENTS:
        #    out += linenumber() + "(" + pathobj.Label + ")\n"

        for c in pathobj.Path.Commands:
            commandlist = [
            ]  # list of elements in the command, code and params.
            command = c.Name.strip()  # command M or G code or comment string
            commandlist.append(command)

            # if modal: only print the command if it is not the same as the last one
            if MODAL is True:
                if command == lastcommand:
                    commandlist.pop(0)

            if c.Name[0] == "(" and not OUTPUT_COMMENTS:  # command is a comment
                continue

            # Now add the remaining parameters in order
            for param in params:
                if param in c.Parameters:
                    if param == "F" and (
                            currLocation[param] != c.Parameters[param]
                            or REPEAT_ARGUMENTS):
                        if c.Name not in ["G0", "G00"]:  # No F in G0
                            speed = Units.Quantity(c.Parameters["F"],
                                                   FreeCAD.Units.Velocity)
                            if speed.getValueAs(UNIT_SPEED_FORMAT) > 0.0:
                                commandlist.append(param + format(
                                    float(speed.getValueAs(UNIT_SPEED_FORMAT)),
                                    precision_string,
                                ))
                        else:
                            continue
                    elif param == "T":
                        commandlist.append(param + str(int(c.Parameters["T"])))
                    elif param == "H":
                        commandlist.append(param + str(int(c.Parameters["H"])))
                    elif param == "D":
                        commandlist.append(param + str(int(c.Parameters["D"])))
                    elif param == "S":
                        commandlist.append(param + str(int(c.Parameters["S"])))
                    else:
                        if ((not REPEAT_ARGUMENTS) and (param in currLocation)
                                and
                            (currLocation[param] == c.Parameters[param])):
                            continue
                        else:
                            pos = Units.Quantity(c.Parameters[param],
                                                 FreeCAD.Units.Length)
                            commandlist.append(
                                param +
                                format(float(pos.getValueAs(UNIT_FORMAT)),
                                       precision_string))

            # store the latest command
            lastcommand = command
            currLocation.update(c.Parameters)

            # Check for Tool Change:
            if command == "M6":
                for line in TOOL_CHANGE.splitlines(True):
                    out += linenumber() + line

                # add height offset
                if USE_TLO:
                    tool_height = "\nG43 H" + str(int(c.Parameters["T"]))
                    commandlist.append(tool_height)

            if command == "message":
                if OUTPUT_COMMENTS is False:
                    out = []
                else:
                    commandlist.pop(0)  # remove the command

            # prepend a line number and append a newline
            if len(commandlist) >= 1:
                if OUTPUT_LINE_NUMBERS:
                    commandlist.insert(0, (linenumber()))

                # append the line to the final output
                for w in commandlist:
                    out += w.strip() + COMMAND_SPACE
                if trace_gcode:
                    print("parse : >>{}".format(out))
                out = out.strip() + "\n"

        return out
示例#49
0
    def execute(self, obj):
        output = ""
        toolLoad = PathUtils.getLastToolLoad(obj)
        if toolLoad is None or toolLoad.ToolNumber == 0:
            self.vertFeed = 100
            self.horizFeed = 100
            self.radius = 0.25
            obj.ToolNumber = 0
            obj.ToolDescription = "UNDEFINED"

        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
            self.radius = tool.Diameter/2
            obj.ToolNumber = toolLoad.ToolNumber
            obj.ToolDescription = toolLoad.Name

        if obj.UserLabel == "":
            obj.Label = obj.Name + " (" + obj.ToolDescription + ")"
        else:
            obj.Label = obj.UserLabel + " (" + obj.ToolDescription + ")"

        locations = []
        output = "(Begin Drilling)\n"
        if obj.Base:
            for loc in obj.Base:
                for sub in loc[1]:

                    if "Face" in sub or "Edge" in sub:
                        s = getattr(loc[0].Shape, sub)
                    else:
                        s = loc[0].Shape

                    if s.ShapeType in ['Wire', 'Edge']:
                        X = s.Edges[0].Curve.Center.x
                        Y = s.Edges[0].Curve.Center.y
                        Z = s.Edges[0].Curve.Center.z
                    elif s.ShapeType in ['Vertex']:
                        X = s.Point.x
                        Y = s.Point.y
                        Z = s.Point.z
                    elif s.ShapeType in ['Face']:
                        #if abs(s.normalAt(0, 0).z) == 1:  # horizontal face
                        X = s.CenterOfMass.x
                        Y = s.CenterOfMass.y
                        Z = s.CenterOfMass.z
                    locations.append(FreeCAD.Vector(X, Y, Z))


            output += "G90 G98\n"
            # rapid to clearance height
            output += "G0 Z" + str(obj.ClearanceHeight.Value)
            # rapid to first hole location, with spindle still retracted:
            p0 = locations[0]
            output += "G0 X" + fmt(p0.x) + " Y" + fmt(p0.y) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(obj.ClearanceHeight.Value) + "\n"
            if obj.PeckDepth.Value > 0:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            else:
                cmd = "G81"
                qword = ""
            for p in locations:
                output += cmd + \
                    " X" + fmt(p.x) + \
                    " Y" + fmt(p.y) + \
                    " Z" + fmt(obj.FinalDepth.Value) + qword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

        path = Path.Path(output)
        obj.Path = path
示例#50
0
def GenerateGCode(op, obj, adaptiveResults, helixDiameter):
    # pylint: disable=unused-argument
    if len(adaptiveResults) == 0 or len(
            adaptiveResults[0]["AdaptivePaths"]) == 0:
        return

    # minLiftDistance = op.tool.Diameter
    helixRadius = 0
    for region in adaptiveResults:
        p1 = region["HelixCenterPoint"]
        p2 = region["StartPoint"]
        r = math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) *
                      (p1[1] - p2[1]))
        if r > helixRadius:
            helixRadius = r

    stepDown = obj.StepDown.Value
    passStartDepth = obj.StartDepth.Value

    if stepDown < 0.1:
        stepDown = 0.1

    length = 2 * math.pi * helixRadius

    if float(obj.HelixAngle) < 1:
        obj.HelixAngle = 1
    if float(obj.HelixAngle) > 89:
        obj.HelixAngle = 89

    if float(obj.HelixConeAngle) < 0:
        obj.HelixConeAngle = 0

    helixAngleRad = math.pi * float(obj.HelixAngle) / 180.0
    depthPerOneCircle = length * math.tan(helixAngleRad)
    # print("Helix circle depth: {}".format(depthPerOneCircle))

    stepUp = obj.LiftDistance.Value
    if stepUp < 0:
        stepUp = 0

    finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0
    if finish_step > stepDown:
        finish_step = stepDown

    depth_params = PathUtils.depth_params(
        clearance_height=obj.ClearanceHeight.Value,
        safe_height=obj.SafeHeight.Value,
        start_depth=obj.StartDepth.Value,
        step_down=stepDown,
        z_finish_step=finish_step,
        final_depth=obj.FinalDepth.Value,
        user_depths=None)

    # ml: this is dangerous because it'll hide all unused variables hence forward
    #     however, I don't know what lx and ly signify so I'll leave them for now
    # pylint: disable=unused-variable
    # lx = adaptiveResults[0]["HelixCenterPoint"][0]
    # ly = adaptiveResults[0]["HelixCenterPoint"][1]
    lz = passStartDepth
    step = 0

    for passEndDepth in depth_params.data:
        step = step + 1

        for region in adaptiveResults:
            startAngle = math.atan2(
                region["StartPoint"][1] - region["HelixCenterPoint"][1],
                region["StartPoint"][0] - region["HelixCenterPoint"][0])

            # lx = region["HelixCenterPoint"][0]
            # ly = region["HelixCenterPoint"][1]

            passDepth = (passStartDepth - passEndDepth)

            p1 = region["HelixCenterPoint"]
            p2 = region["StartPoint"]
            helixRadius = math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) +
                                    (p1[1] - p2[1]) * (p1[1] - p2[1]))

            # Helix ramp
            if helixRadius > 0.01:
                r = helixRadius - 0.01

                maxfi = passDepth / depthPerOneCircle * 2 * math.pi
                fi = 0
                offsetFi = -maxfi + startAngle - math.pi / 16

                helixStart = [
                    region["HelixCenterPoint"][0] + r * math.cos(offsetFi),
                    region["HelixCenterPoint"][1] + r * math.sin(offsetFi)
                ]

                op.commandlist.append(
                    Path.Command("(Helix to depth: %f)" % passEndDepth))

                if obj.UseHelixArcs is False:
                    # rapid move to start point
                    op.commandlist.append(
                        Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.ClearanceHeight.Value
                            }))

                    # rapid move to safe height
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.SafeHeight.Value
                            }))

                    # move to start depth
                    op.commandlist.append(
                        Path.Command(
                            "G1", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": passStartDepth,
                                "F": op.vertFeed
                            }))

                    if obj.HelixConeAngle == 0:
                        while fi < maxfi:
                            x = region["HelixCenterPoint"][0] + r * math.cos(
                                fi + offsetFi)
                            y = region["HelixCenterPoint"][1] + r * math.sin(
                                fi + offsetFi)
                            z = passStartDepth - fi / maxfi * (passStartDepth -
                                                               passEndDepth)
                            op.commandlist.append(
                                Path.Command("G1", {
                                    "X": x,
                                    "Y": y,
                                    "Z": z,
                                    "F": op.vertFeed
                                }))
                            # lx = x
                            # ly = y
                            fi = fi + math.pi / 16

                        # one more circle at target depth to make sure center is cleared
                        maxfi = maxfi + 2 * math.pi
                        while fi < maxfi:
                            x = region["HelixCenterPoint"][0] + r * math.cos(
                                fi + offsetFi)
                            y = region["HelixCenterPoint"][1] + r * math.sin(
                                fi + offsetFi)
                            z = passEndDepth
                            op.commandlist.append(
                                Path.Command("G1", {
                                    "X": x,
                                    "Y": y,
                                    "Z": z,
                                    "F": op.horizFeed
                                }))
                            # lx = x
                            # ly = y
                            fi = fi + math.pi / 16

                    else:
                        # Cone
                        _HelixAngle = 360 - (float(obj.HelixAngle) * 4)

                        if obj.HelixConeAngle > 6:
                            obj.HelixConeAngle = 6

                        helixRadius *= 0.9

                        # Calculate everything
                        helix_height = passStartDepth - passEndDepth
                        r_extra = helix_height * math.tan(
                            math.radians(obj.HelixConeAngle))
                        HelixTopRadius = helixRadius + r_extra
                        helix_full_height = HelixTopRadius * (
                            math.cos(math.radians(obj.HelixConeAngle)) /
                            math.sin(math.radians(obj.HelixConeAngle)))

                        # Start height
                        z = passStartDepth
                        i = 0

                        # Default step down
                        z_step = 0.05

                        # Bigger angle, smaller step down
                        if _HelixAngle > 120:
                            z_step = 0.025
                        if _HelixAngle > 240:
                            z_step = 0.015

                        p = None
                        # Calculate conical helix
                        while (z >= passEndDepth):
                            if z < passEndDepth:
                                z = passEndDepth

                            p = CalcHelixConePoint(helix_full_height, i,
                                                   HelixTopRadius, _HelixAngle)
                            op.commandlist.append(
                                Path.Command(
                                    "G1", {
                                        "X":
                                        p['X'] + region["HelixCenterPoint"][0],
                                        "Y":
                                        p['Y'] + region["HelixCenterPoint"][1],
                                        "Z": z,
                                        "F": op.vertFeed
                                    }))
                            z = z - z_step
                            i = i + z_step

                        # Calculate some stuff for arcs at bottom
                        p['X'] = p['X'] + region["HelixCenterPoint"][0]
                        p['Y'] = p['Y'] + region["HelixCenterPoint"][1]
                        x_m = region["HelixCenterPoint"][0] - p['X'] + region[
                            "HelixCenterPoint"][0]
                        y_m = region["HelixCenterPoint"][1] - p['Y'] + region[
                            "HelixCenterPoint"][1]
                        i_off = (x_m - p['X']) / 2
                        j_off = (y_m - p['Y']) / 2

                        # One more circle at target depth to make sure center is cleared
                        op.commandlist.append(
                            Path.Command(
                                "G3", {
                                    "X": x_m,
                                    "Y": y_m,
                                    "Z": passEndDepth,
                                    "I": i_off,
                                    "J": j_off,
                                    "F": op.horizFeed
                                }))
                        op.commandlist.append(
                            Path.Command(
                                "G3", {
                                    "X": p['X'],
                                    "Y": p['Y'],
                                    "Z": passEndDepth,
                                    "I": -i_off,
                                    "J": -j_off,
                                    "F": op.horizFeed
                                }))

                else:
                    # Use arcs for helix - no conical shape support
                    helixStart = [
                        region["HelixCenterPoint"][0] + r,
                        region["HelixCenterPoint"][1]
                    ]

                    # rapid move to start point
                    op.commandlist.append(
                        Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.ClearanceHeight.Value
                            }))

                    # rapid move to safe height
                    op.commandlist.append(
                        Path.Command(
                            "G0", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": obj.SafeHeight.Value
                            }))

                    # move to start depth
                    op.commandlist.append(
                        Path.Command(
                            "G1", {
                                "X": helixStart[0],
                                "Y": helixStart[1],
                                "Z": passStartDepth,
                                "F": op.vertFeed
                            }))

                    x = region["HelixCenterPoint"][0] + r
                    y = region["HelixCenterPoint"][1]

                    curDep = passStartDepth
                    while curDep > (passEndDepth + depthPerOneCircle):
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x - (2 * r),
                                    "Y": y,
                                    "Z": curDep - (depthPerOneCircle / 2),
                                    "I": -r,
                                    "F": op.vertFeed
                                }))
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x,
                                    "Y": y,
                                    "Z": curDep - depthPerOneCircle,
                                    "I": r,
                                    "F": op.vertFeed
                                }))
                        curDep = curDep - depthPerOneCircle

                    lastStep = curDep - passEndDepth
                    if lastStep > (depthPerOneCircle / 2):
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x - (2 * r),
                                    "Y": y,
                                    "Z": curDep - (lastStep / 2),
                                    "I": -r,
                                    "F": op.vertFeed
                                }))
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x,
                                    "Y": y,
                                    "Z": passEndDepth,
                                    "I": r,
                                    "F": op.vertFeed
                                }))
                    else:
                        op.commandlist.append(
                            Path.Command(
                                "G2", {
                                    "X": x - (2 * r),
                                    "Y": y,
                                    "Z": passEndDepth,
                                    "I": -r,
                                    "F": op.vertFeed
                                }))
                        op.commandlist.append(
                            Path.Command(
                                "G1", {
                                    "X": x,
                                    "Y": y,
                                    "Z": passEndDepth,
                                    "F": op.vertFeed
                                }))

                    # one more circle at target depth to make sure center is cleared
                    op.commandlist.append(
                        Path.Command(
                            "G2", {
                                "X": x - (2 * r),
                                "Y": y,
                                "Z": passEndDepth,
                                "I": -r,
                                "F": op.horizFeed
                            }))
                    op.commandlist.append(
                        Path.Command(
                            "G2", {
                                "X": x,
                                "Y": y,
                                "Z": passEndDepth,
                                "I": r,
                                "F": op.horizFeed
                            }))
                    # lx = x
                    # ly = y

            else:  # no helix entry
                # rapid move to clearance height
                op.commandlist.append(
                    Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
                op.commandlist.append(
                    Path.Command(
                        "G0", {
                            "X": region["StartPoint"][0],
                            "Y": region["StartPoint"][1],
                            "Z": obj.ClearanceHeight.Value
                        }))
                # straight plunge to target depth
                op.commandlist.append(
                    Path.Command(
                        "G1", {
                            "X": region["StartPoint"][0],
                            "Y": region["StartPoint"][1],
                            "Z": passEndDepth,
                            "F": op.vertFeed
                        }))

            lz = passEndDepth
            z = obj.ClearanceHeight.Value
            op.commandlist.append(
                Path.Command("(Adaptive - depth: %f)" % passEndDepth))

            # add adaptive paths
            for pth in region["AdaptivePaths"]:
                motionType = pth[0]  # [0] contains motion type

                for pt in pth[1]:  # [1] contains list of points
                    x = pt[0]
                    y = pt[1]

                    # dist = math.sqrt((x-lx)*(x-lx) + (y-ly)*(y-ly))

                    if motionType == area.AdaptiveMotionType.Cutting:
                        z = passEndDepth
                        if z != lz:
                            op.commandlist.append(
                                Path.Command("G1", {
                                    "Z": z,
                                    "F": op.vertFeed
                                }))

                        op.commandlist.append(
                            Path.Command("G1", {
                                "X": x,
                                "Y": y,
                                "F": op.horizFeed
                            }))

                    elif motionType == area.AdaptiveMotionType.LinkClear:
                        z = passEndDepth + stepUp
                        if z != lz:
                            op.commandlist.append(Path.Command("G0", {"Z": z}))

                        op.commandlist.append(
                            Path.Command("G0", {
                                "X": x,
                                "Y": y
                            }))

                    elif motionType == area.AdaptiveMotionType.LinkNotClear:
                        z = obj.ClearanceHeight.Value
                        if z != lz:
                            op.commandlist.append(Path.Command("G0", {"Z": z}))

                        op.commandlist.append(
                            Path.Command("G0", {
                                "X": x,
                                "Y": y
                            }))

                    # elif motionType == area.AdaptiveMotionType.LinkClearAtPrevPass:
                    #     if lx!=x or ly!=y:
                    #         op.commandlist.append(Path.Command("G0", { "X": lx, "Y":ly, "Z":passStartDepth+stepUp}))
                    #     op.commandlist.append(Path.Command("G0", { "X": x, "Y":y, "Z":passStartDepth+stepUp}))

                    # lx = x
                    # ly = y
                    lz = z

            # return to safe height in this Z pass
            z = obj.ClearanceHeight.Value
            if z != lz:
                op.commandlist.append(Path.Command("G0", {"Z": z}))

            lz = z

        passStartDepth = passEndDepth

        # return to safe height in this Z pass
        z = obj.ClearanceHeight.Value
        if z != lz:
            op.commandlist.append(Path.Command("G0", {"Z": z}))

        lz = z

    z = obj.ClearanceHeight.Value
    if z != lz:
        op.commandlist.append(Path.Command("G0", {"Z": z}))

    lz = z
示例#51
0
def load_train(depth=0):
    """
    Load dataset for training and validating.

    *NOTE*  If you need a validating set, you SHOULD split from training set
    by yourself.


    Args
    ----
    depth: int, 0 by default
    Maximum moves of time window. 0 means no need to move time window.


    Returns
    -------
    X: numpy ndarray, shape: (num_of_enrollments, num_of_features)
    Rows of features. It is the features of all time if cache_only is True.

    y: numpy ndarray, shape: (num_of_enrollments,)
    Vector of labels. It is the labels of all time if cache_only is True.
    """
    logger.debug('loading train set of depth %d', depth)

    enroll_set = IO.load_enrollment_train()
    log_all = IO.load_logs()
    base_date = datetime(2014, 8, 1, 22, 0, 47)

    logger.debug('loading features before %s', base_date)

    enroll_ids = __enroll_ids_with_log__(log_all, enroll_set['enrollment_id'],
                                         base_date)

    pkl_X_path = Path.of_cache('train_X.%s.pkl' % base_date)
    pkl_y_path = Path.of_cache('train_y.%s.pkl' % base_date)

    X = IO.fetch_cache(pkl_X_path)
    y = IO.fetch_cache(pkl_y_path)

    if X is None or y is None:
        logger.debug('cache missed, calculating ...')

        X, _ = __load_dataset__(log_all, enroll_ids, base_date)
        y_with_id = IO.load_train_y()

        y = np.array(pd.merge(enroll_set, y_with_id, how='left',
                              on='enrollment_id')['y'])
        if np.any(np.isnan(y)):
            logger.fatal('something wrong with y')
            raise RuntimeError('something wrong with y')

        IO.cache(X, pkl_X_path)
        IO.cache(y, pkl_y_path)

    base_date = datetime(2014, 7, 22, 22, 0, 47)
    Dw = timedelta(days=7)

    enroll_ids = __enroll_ids_with_log__(log_all, enroll_ids, base_date)
    for _ in range(depth):
        if enroll_ids.size <= 0:
            break

        logger.debug('loading features before %s', base_date)

        # get instances and labels
        pkl_X_path = Path.of_cache('train_X.%s.pkl' % base_date)
        pkl_y_path = Path.of_cache('train_y.%s.pkl' % base_date)

        X_temp = IO.fetch_cache(pkl_X_path)
        y_temp = IO.fetch_cache(pkl_y_path)
        if X_temp is None or y_temp is None:
            logger.debug('cache missed, calculating ...')

            X_temp, y_temp = __load_dataset__(log_all, enroll_ids, base_date)

            IO.cache(X_temp, pkl_X_path)
            IO.cache(y_temp, pkl_y_path)

        # update instances and labels
        X = np.r_[X, X_temp]
        y = np.append(y, y_temp)

        # update base_date and enroll_ids
        base_date -= Dw
        enroll_ids = __enroll_ids_with_log__(log_all, enroll_ids, base_date)

    logger.debug('train set loaded')

    if np.any(np.isinf(X)):
        logger.debug('train set has INF')
    return X, y
示例#52
0
    def circularHoleExecute(self, obj, holes):
        '''circularHoleExecute(obj, holes) ... generate drill operation for each hole in holes.'''
        PathLog.track()
        PathLog.debug("\ncircularHoleExecute() in PathDrilling.py")

        lastAxis = None
        lastAngle = 0.0

        self.commandlist.append(Path.Command("(Begin Drilling)"))

        # rapid to clearance height
        self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))

        tiplength = 0.0
        if obj.AddTipLength:
            tiplength = PathUtils.drillTipLength(self.tool)

        holes = PathUtils.sort_jobs(holes, ['x', 'y'])
        self.commandlist.append(Path.Command('G90'))
        self.commandlist.append(Path.Command(obj.ReturnLevel))

        # ml: I'm not sure whey these were here, they seem redundant
        # # rapid to first hole location, with spindle still retracted:
        # p0 = holes[0]
        # self.commandlist.append(Path.Command('G0', {'X': p0['x'], 'Y': p0['y'], 'F': self.horizRapid}))
        # # move tool to clearance plane
        # self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))

        for p in holes:
            cmd = "G81"
            cmdParams = {}
            cmdParams['Z'] = p['trgtDep'] - tiplength
            cmdParams['F'] = self.vertFeed
            cmdParams['R'] = obj.RetractHeight.Value
            if obj.PeckEnabled and obj.PeckDepth.Value > 0:
                cmd = "G83"
                cmdParams['Q'] = obj.PeckDepth.Value
            elif obj.DwellEnabled and obj.DwellTime > 0:
                cmd = "G82"
                cmdParams['P'] = obj.DwellTime

            params = {}
            params['X'] = p['x']
            params['Y'] = p['y']
            params.update(cmdParams)
            if obj.EnableRotation != 'Off':
                angle = p['angle']
                axis = p['axis']
                # Rotate model to index for hole
                if axis == 'X':
                    axisOfRot = 'A'
                elif axis == 'Y':
                    axisOfRot = 'B'
                    # Reverse angle temporarily to match model. Error in FreeCAD render of B axis rotations
                    if obj.B_AxisErrorOverride is True:
                        angle = -1 * angle
                elif axis == 'Z':
                    axisOfRot = 'C'
                else:
                    axisOfRot = 'A'

                # Set initial values for last axis and angle
                if lastAxis is None:
                    lastAxis = axisOfRot
                    lastAngle = angle

                # Handle axial and angular transitions
                if axisOfRot != lastAxis:
                    self.commandlist.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))
                    self.commandlist.append(Path.Command('G0', {lastAxis: 0.0, 'F': self.axialRapid}))
                elif angle != lastAngle:
                    self.commandlist.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))

                # Prepare for drilling cycle
                self.commandlist.append(Path.Command('G0', {axisOfRot: angle, 'F': self.axialRapid}))
                self.commandlist.append(Path.Command('G0', {'X': p['x'], 'Y': p['y'], 'F': self.horizRapid}))
                self.commandlist.append(Path.Command('G1', {'Z': p['stkTop'], 'F': self.vertFeed}))

            # Perform and cancel canned drilling cycle
            self.commandlist.append(Path.Command(cmd, params))
            self.commandlist.append(Path.Command('G80'))

            # shift axis and angle values
            if obj.EnableRotation != 'Off':
                lastAxis = axisOfRot
                lastAngle = angle

        if obj.EnableRotation != 'Off':
            self.commandlist.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))
            self.commandlist.append(Path.Command('G0', {lastAxis: 0.0, 'F': self.axialRapid}))
示例#53
0
时间:2014年12月16日 
创建人:李胤龙
"""
import interface_token
import urllib
import urllib2
import json
import unittest
import time
import HTMLTestRunner
import Path

# 定义要创建的目录
Testjresult="E:\\Test jresult\\interface\\"
# 调用函数
Path.mkdir(Testjresult)

# 获取fctoken
fctoken = interface_token.fctoken()

class interface(unittest.TestCase):
    def setUp(self):
        pass
    
#获取某个当前账户的详细信息/GET方式
    def info_account(self):
                
        url = "http://dev.cdnboss.fastweb.com.cn/innerapi.php/Base/info_account"
        req = url+'/fctoken/'+fctoken +'/fcname/fastweb/user_id/142'
        res_data = urllib2.urlopen(req)
        res = res_data.read()
示例#54
0
def internalThreadCommands(loc, cmd, zStart, zFinal, pitch, radius, leadInOut):
    '''internalThreadCommands(loc, cmd, zStart, zFinal, pitch, radius) ... returns the g-code to mill the given internal thread'''
    thread = _InternalThread(cmd, zStart, zFinal, pitch)

    yMin = loc.y - radius
    yMax = loc.y + radius

    path = []
    # at this point the tool is at a safe height (depending on the previous thread), so we can move
    # into position first, and then drop to the start height. If there is any material in the way this
    # op hasn't been setup properly.
    path.append(Path.Command('G0', {'X': loc.x, 'Y': loc.y}))
    path.append(Path.Command('G0', {'Z': thread.zStart}))
    if leadInOut:
        path.append(
            Path.Command(thread.cmd, {
                'Y': yMax,
                'J': (yMax - loc.y) / 2
            }))
    else:
        path.append(Path.Command('G1', {'Y': yMax}))

    z = thread.zStart
    r = -radius
    i = 0
    while True:
        z = thread.zStart + i * thread.hPitch
        if thread.overshoots(z):
            break
        if 0 == (i & 0x01):
            y = yMin
        else:
            y = yMax
        path.append(
            Path.Command(thread.cmd, {
                'Y': y,
                'Z': z + thread.hPitch,
                'J': r
            }))
        r = -r
        i = i + 1

    z = thread.zStart + i * thread.hPitch
    if PathGeom.isRoughly(z, thread.zFinal):
        x = loc.x
    else:
        n = math.fabs(thread.zFinal - thread.zStart) / thread.hPitch
        k = n - int(n)
        dy = math.cos(k * math.pi)
        dx = math.sin(k * math.pi)
        y = thread.adjustY(loc.y, r * dy)
        x = thread.adjustX(loc.x, r * dx)
        path.append(
            Path.Command(thread.cmd, {
                'X': x,
                'Y': y,
                'Z': thread.zFinal,
                'J': r
            }))

    if leadInOut:
        path.append(
            Path.Command(thread.cmd, {
                'X': loc.x,
                'Y': loc.y,
                'I': (loc.x - x) / 2,
                'J': (loc.y - y) / 2
            }))
    else:
        path.append(Path.Command('G1', {'X': loc.x, 'Y': loc.y}))
    return path
示例#55
0
    def createPath(self, obj, pathData, tags):
        PathLog.track()
        commands = []
        lastEdge = 0
        lastTag = 0
        # sameTag = None
        t = 0
        # inters = None
        edge = None

        segm = 50
        if hasattr(obj, 'SegmentationFactor'):
            segm = obj.SegmentationFactor
            if segm <= 0:
                segm = 50
                obj.SegmentationFactor = 50

        self.mappers = []
        mapper = None

        tc = PathDressup.toolController(obj.Base)
        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        while edge or lastEdge < len(pathData.edges):
            PathLog.debug("------- lastEdge = %d/%d.%d/%d" %
                          (lastEdge, lastTag, t, len(tags)))
            if not edge:
                edge = pathData.edges[lastEdge]
                debugEdge(
                    edge, "=======  new edge: %d/%d" %
                    (lastEdge, len(pathData.edges)))
                lastEdge += 1
                # sameTag = None

            if mapper:
                mapper.add(edge)
                if mapper.mappingComplete():
                    commands.extend(mapper.commands)
                    edge = mapper.tail
                    mapper = None
                else:
                    edge = None

            if edge:
                tIndex = (t + lastTag) % len(tags)
                t += 1
                i = tags[tIndex].intersects(edge, edge.FirstParameter)
                if i and self.isValidTagStartIntersection(edge, i):
                    mapper = MapWireToTag(edge,
                                          tags[tIndex],
                                          i,
                                          segm,
                                          pathData.maxZ,
                                          hSpeed=horizFeed,
                                          vSpeed=vertFeed)
                    self.mappers.append(mapper)
                    edge = mapper.tail

            if not mapper and t >= len(tags):
                # gone through all tags, consume edge and move on
                if edge:
                    debugEdge(edge, '++++++++')
                    if pathData.rapid.isRapid(edge):
                        v = edge.Vertexes[1]
                        if not commands and PathGeom.isRoughly(
                                0, v.X) and PathGeom.isRoughly(
                                    0, v.Y) and not PathGeom.isRoughly(0, v.Z):
                            # The very first move is just to move to ClearanceHeight
                            commands.append(
                                Path.Command('G0', {
                                    'Z': v.Z,
                                    'F': horizRapid
                                }))
                        else:
                            commands.append(
                                Path.Command('G0', {
                                    'X': v.X,
                                    'Y': v.Y,
                                    'Z': v.Z,
                                    'F': vertRapid
                                }))
                    else:
                        commands.extend(
                            PathGeom.cmdsForEdge(edge,
                                                 segm=segm,
                                                 hSpeed=horizFeed,
                                                 vSpeed=vertFeed))
                edge = None
                t = 0

        return Path.Path(commands)
示例#56
0
    def arcTwist(self, obj, queue, lastXY, twistCW=False):
        '''returns gcode to do an arc move toward an arc to perform
        a corner action twist. Inclues lifting and plungeing the knife'''

        global currLocation
        pivotheight = obj.pivotheight
        offset = obj.offset
        results = []

        # set the correct twist command
        if twistCW is False:
            arcdir = "G3"
        else:
            arcdir = "G2"

        # move to the pivot heigth
        zdepth = currLocation["Z"]
        retract = Path.Command("G0", {"Z": pivotheight})
        results.append(retract)
        currLocation.update(retract.Parameters)

        # get the center of the destination arc
        arccenter = FreeCAD.Base.Vector(queue[1].x + queue[0].I,
                                        queue[1].y + queue[0].J,
                                        currLocation["Z"])

        # The center of the twist arc is the old line end point.
        C = queue[1].Placement.Base

        # Find radius of old arc
        R = math.hypot(queue[0].I, queue[0].J)

        # find angle of original center to startpoint
        v1 = queue[1].Placement.Base.sub(arccenter)
        segAngle = D.angle(v1, FreeCAD.Base.Vector(1, 0, 0),
                           FreeCAD.Base.Vector(0, 0, -1))

        # Find angle subtended by the offset
        theta = offset / R

        # add or subtract theta depending on direction
        if queue[1].Name in ["G2", "G02"]:
            newangle = segAngle + theta
        else:
            newangle = segAngle - theta

        # calculate endpoints
        Bx = arccenter.x + R * math.cos(newangle)
        By = arccenter.y + R * math.sin(newangle)
        endpointvector = FreeCAD.Base.Vector(Bx, By, currLocation['Z'])

        # calculate IJ offsets of twist arc from current position.
        offsetvector = C.sub(lastXY)

        # add G2/G3 move
        arcmove = Path.Command(
            arcdir, {
                "X": endpointvector.x,
                "Y": endpointvector.y,
                "I": offsetvector.x,
                "J": offsetvector.y
            })
        results.append(arcmove)
        currLocation.update(arcmove.Parameters)

        # plunge back to depth
        plunge = Path.Command("G1", {"Z": zdepth})
        results.append(plunge)
        currLocation.update(plunge.Parameters)

        # The old arc move won't work so calculate a replacement command
        offsetv = arccenter.sub(endpointvector)

        replace = Path.Command(queue[0].Name, {
            "X": queue[0].X,
            "Y": queue[0].Y,
            "I": offsetv.x,
            "J": offsetv.y
        })
        return (results, replace)