PartDesign: Add true threads to Hole
- Thread runout according to DIN 76-1
- Through all length updated to be calculated based on bounding box
- New properties: ModelThread, ThreadDepthType, ThreadDepth,
UseCustomThreadClearance, CustomThreadClearance
- Rename Old but unused parameters related to thread modeling.
- Functionality exposed in UI
This commit is contained in:
@@ -50,6 +50,11 @@
|
||||
# include <BRepAlgoAPI_Fuse.hxx>
|
||||
# include <Standard_Version.hxx>
|
||||
# include <QCoreApplication>
|
||||
# include <BRepOffsetAPI_MakePipeShell.hxx>
|
||||
# include <BRepBuilderAPI_Sewing.hxx>
|
||||
# include <BRepClass3d_SolidClassifier.hxx>
|
||||
# include <BRepBuilderAPI_MakeSolid.hxx>
|
||||
# include <gp_Ax1.hxx>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -61,6 +66,7 @@
|
||||
#include <App/Application.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include <Mod/Part/App/FaceMakerCheese.h>
|
||||
|
||||
#include "json.hpp"
|
||||
#include "FeatureHole.h"
|
||||
@@ -70,6 +76,7 @@ namespace PartDesign {
|
||||
/* TRANSLATOR PartDesign::Hole */
|
||||
|
||||
const char* Hole::DepthTypeEnums[] = { "Dimension", "ThroughAll", /*, "UpToFirst", */ NULL };
|
||||
const char* Hole::ThreadDepthTypeEnums[] = { "Automatic", "Dimension", NULL };
|
||||
const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", NULL};
|
||||
const char* Hole::ClearanceMetricEnums[] = { "Standard", "Close", "Wide", NULL};
|
||||
const char* Hole::ClearanceUTSEnums[] = { "Normal", "Close", "Loose", NULL };
|
||||
@@ -542,6 +549,67 @@ const char* Hole::ThreadSize_ISOmetricfine_Enums[] = {
|
||||
"M100x2.0", "M100x3.0", "M100x4.0", "M100x6.0", NULL };
|
||||
const char* Hole::ThreadClass_ISOmetricfine_Enums[] = { "4G", "4H", "5G", "5H", "6G", "6H", "7G", "7H","8G", "8H", NULL };
|
||||
|
||||
// ISO 965-1:2013 ISO general purpose metric screw threads - Tolerances - Part 1
|
||||
// Table 1 - Fundamentral deviations for internal threads ...
|
||||
// reproduced in: https://www.accu.co.uk/en/p/134-iso-metric-thread-tolerances [retrived: 2021-01-11]
|
||||
const double Hole::ThreadClass_ISOmetric_data[ThreadClass_ISOmetric_data_size][2] = {
|
||||
// Pitch G
|
||||
{0.2, 0.017},
|
||||
{0.25, 0.018},
|
||||
{0.3, 0.018},
|
||||
{0.35, 0.019},
|
||||
{0.4, 0.019},
|
||||
{0.45, 0.020},
|
||||
{0.5, 0.020},
|
||||
{0.6, 0.021},
|
||||
{0.7, 0.022},
|
||||
{0.75, 0.022},
|
||||
{0.8, 0.024},
|
||||
{1.0, 0.026},
|
||||
{1.25, 0.028},
|
||||
{1.5, 0.032},
|
||||
{1.75, 0.034},
|
||||
{2.0, 0.038},
|
||||
{2.5, 0.042},
|
||||
{3.0, 0.048},
|
||||
{3.5, 0.053},
|
||||
{4.0, 0.060},
|
||||
{4.5, 0.063},
|
||||
{5.0, 0.071},
|
||||
{5.5, 0.075},
|
||||
{6.0, 0.080},
|
||||
{8.0, 0.100}
|
||||
};
|
||||
|
||||
/* According to DIN 76-1 (Thread run-outs and thread undercuts - Part 1: For ISO metric threads in accordance with DIN 13-1) */
|
||||
const double Hole::ThreadRunout[ThreadRunout_size][2] = {
|
||||
// Pitch e1
|
||||
{0.2, 1.3},
|
||||
{0.25, 1.5},
|
||||
{0.3, 1.8},
|
||||
{0.35, 2.1},
|
||||
{0.4, 2.3},
|
||||
{0.45, 2.6},
|
||||
{0.5, 2.8},
|
||||
{0.6, 3.4},
|
||||
{0.7, 3.8},
|
||||
{0.75, 4.0},
|
||||
{0.8, 4.2},
|
||||
{1.0, 5.1},
|
||||
{1.25, 6.2},
|
||||
{1.5, 7.3},
|
||||
{1.75, 8.3},
|
||||
{2.0, 9.3},
|
||||
{2.5, 11.2},
|
||||
{3.0, 13.1},
|
||||
{3.5, 15.2},
|
||||
{4.0, 16.8},
|
||||
{4.5, 18.4},
|
||||
{5.0, 20.8},
|
||||
{5.5, 22.4},
|
||||
{6.0, 24.0}
|
||||
};
|
||||
|
||||
/* Details from https://en.wikipedia.org/wiki/Unified_Thread_Standard */
|
||||
|
||||
/* UTS coarse */
|
||||
@@ -585,11 +653,7 @@ Hole::Hole()
|
||||
|
||||
ADD_PROPERTY_TYPE(Threaded, (false), "Hole", App::Prop_None, "Threaded");
|
||||
|
||||
ADD_PROPERTY_TYPE(ModelActualThread, (false), "Hole", App::Prop_None, "Model actual thread");
|
||||
ADD_PROPERTY_TYPE(ThreadPitch, (0.0), "Hole", App::Prop_None, "Thread pitch");
|
||||
ADD_PROPERTY_TYPE(ThreadAngle, (0.0), "Hole", App::Prop_None, "Thread angle");
|
||||
ADD_PROPERTY_TYPE(ThreadCutOffInner, (0.0), "Hole", App::Prop_None, "Thread CutOff Inner");
|
||||
ADD_PROPERTY_TYPE(ThreadCutOffOuter, (0.0), "Hole", App::Prop_None, "Thread CutOff Outer");
|
||||
ADD_PROPERTY_TYPE(ModelThread, (false), "Hole", App::Prop_None, "Model actual thread");
|
||||
|
||||
ADD_PROPERTY_TYPE(ThreadType, (0L), "Hole", App::Prop_None, "Thread type");
|
||||
ThreadType.setEnums(ThreadTypeEnums);
|
||||
@@ -635,6 +699,16 @@ Hole::Hole()
|
||||
ADD_PROPERTY_TYPE(Tapered, (false),"Hole", App::Prop_None, "Tapered");
|
||||
|
||||
ADD_PROPERTY_TYPE(TaperedAngle, (90.0), "Hole", App::Prop_None, "Tapered angle");
|
||||
|
||||
ADD_PROPERTY_TYPE(ThreadDepthType, (0L), "Hole", App::Prop_None, "Thread depth type");
|
||||
ThreadDepthType.setEnums(ThreadDepthTypeEnums);
|
||||
|
||||
ADD_PROPERTY_TYPE(ThreadDepth, (23.5), "Hole", App::Prop_None, "Thread Length"); // default is assuming an M1
|
||||
|
||||
ADD_PROPERTY_TYPE(UseCustomThreadClearance, (false), "Hole", App::Prop_None, "Use custom thread clearance");
|
||||
|
||||
ADD_PROPERTY_TYPE(CustomThreadClearance, (0.0), "Hole", App::Prop_None, "Custom thread clearance (overrides ThreadClass)");
|
||||
|
||||
}
|
||||
|
||||
void Hole::updateHoleCutParams()
|
||||
@@ -697,7 +771,7 @@ void Hole::updateHoleCutParams()
|
||||
const CounterSinkDimension& dimen = counter.get_sink(threadSizeStr);
|
||||
if (dimen.diameter != 0.0) {
|
||||
HoleCutDiameter.setValue(dimen.diameter);
|
||||
}
|
||||
}
|
||||
else {
|
||||
HoleCutDiameter.setValue(Diameter.getValue() + 0.1);
|
||||
}
|
||||
@@ -838,7 +912,7 @@ void Hole::updateHoleCutParams()
|
||||
if (HoleCutDiameter.getValue() == 0.0 || HoleCutDiameter.getValue() <= diameterVal) {
|
||||
HoleCutDiameter.setValue(diameterVal * 1.7);
|
||||
// 82 degrees for UTS, 90 otherwise
|
||||
if (threadTypeStr != "None")
|
||||
if (threadTypeStr != "None")
|
||||
HoleCutCountersinkAngle.setValue(82.0);
|
||||
else
|
||||
HoleCutCountersinkAngle.setValue(90.0);
|
||||
@@ -856,6 +930,84 @@ void Hole::updateHoleCutParams()
|
||||
}
|
||||
}
|
||||
|
||||
double Hole::getThreadClassClearance()
|
||||
{
|
||||
double pitch = getThreadPitch();
|
||||
|
||||
// Calulate how much clearance to add based on Thread tolerance class and pitch
|
||||
if (ThreadClass.getValueAsString()[1] == 'G') {
|
||||
for(unsigned int i=0; i<ThreadClass_ISOmetric_data_size; i++) {
|
||||
double p = ThreadClass_ISOmetric_data[i][0];
|
||||
if (pitch <= p) {
|
||||
return ThreadClass_ISOmetric_data[i][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Calculates the distance between the bottom hole and the bottom most thread.
|
||||
// This is defined in DIN 76-1, there are 3 possibilities:
|
||||
// mode=1 (default), For normal cases e1 is wanted.
|
||||
// mode=2, In cases where shorter thread runout is necessary
|
||||
// mode=3, In cases where longer thread runout is necessary
|
||||
double Hole::getThreadRunout(int mode)
|
||||
{
|
||||
double pitch = getThreadPitch();
|
||||
|
||||
double sf = 1.0; // scale factor
|
||||
switch (mode) {
|
||||
case 1:
|
||||
sf = 1.0;
|
||||
break;
|
||||
case 2:
|
||||
sf = 0.625;
|
||||
break;
|
||||
case 3:
|
||||
sf = 1.6;
|
||||
break;
|
||||
default:
|
||||
throw Base::ValueError("Unsupported argument");
|
||||
}
|
||||
for(unsigned int i=0; i<ThreadRunout_size; i++) {
|
||||
double p = ThreadRunout[i][0];
|
||||
if (pitch <= p) {
|
||||
return sf*ThreadRunout[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
// For non-standard pitch we fall back on general engineering rule of thumb of 4*pitch.
|
||||
return 4*pitch;
|
||||
}
|
||||
|
||||
double Hole::getThreadPitch()
|
||||
{
|
||||
int threadType = ThreadType.getValue();
|
||||
int threadSize = ThreadSize.getValue();
|
||||
return threadDescription[threadType][threadSize].pitch;
|
||||
}
|
||||
|
||||
void Hole::updateThreadDepthParam()
|
||||
{
|
||||
std::string method(DepthType.getValueAsString());
|
||||
double drillDepth;
|
||||
if ( method == "Dimension" ) {
|
||||
drillDepth = Depth.getValue();
|
||||
} else if ( method == "ThroughAll" ) {
|
||||
drillDepth = getThroughAllLength();
|
||||
} else {
|
||||
throw Base::RuntimeError("Unsupported depth type \n");
|
||||
}
|
||||
|
||||
if ( std::string(ThreadDepthType.getValueAsString()) == "Automatic" ) {
|
||||
ThreadDepth.setValue(Depth.getValue() - getThreadRunout());
|
||||
if ( method == "ThroughAll" ) {
|
||||
ThreadDepth.setValue(drillDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Hole::updateDiameterParam()
|
||||
{
|
||||
// Diameter parameter depends on Threaded, ThreadType, ThreadSize, and ThreadFit
|
||||
@@ -878,35 +1030,30 @@ void Hole::updateDiameterParam()
|
||||
}
|
||||
double diameter = threadDescription[threadType][threadSize].diameter;
|
||||
double pitch = threadDescription[threadType][threadSize].pitch;
|
||||
double clearance = 0.0;
|
||||
|
||||
if (threadType == 0)
|
||||
return;
|
||||
|
||||
if (Threaded.getValue()) {
|
||||
if (std::string(ThreadType.getValueAsString()) != "None") {
|
||||
double h = pitch * sqrt(3) / 2;
|
||||
|
||||
// Basic profile for ISO and UTS threads
|
||||
ThreadPitch.setValue(pitch);
|
||||
ThreadAngle.setValue(60);
|
||||
ThreadCutOffInner.setValue(h/8);
|
||||
ThreadCutOffOuter.setValue(h/4);
|
||||
}
|
||||
|
||||
if (ModelActualThread.getValue()) {
|
||||
pitch = ThreadPitch.getValue();
|
||||
if (ModelThread.getValue()) {
|
||||
if (UseCustomThreadClearance.getValue())
|
||||
clearance = CustomThreadClearance.getValue();
|
||||
else
|
||||
clearance = getThreadClassClearance();
|
||||
}
|
||||
|
||||
// use normed diameters if possible
|
||||
std::string threadType = ThreadType.getValueAsString();
|
||||
if (threadType == "ISOMetricProfile" || threadType == "UNC"
|
||||
|| threadType == "UNF" || threadType == "UNEF") {
|
||||
diameter = threadDescription[ThreadType.getValue()][ThreadSize.getValue()].CoreHole;
|
||||
}
|
||||
diameter = threadDescription[ThreadType.getValue()][ThreadSize.getValue()].CoreHole + clearance;
|
||||
}
|
||||
// if nothing available, we must calculate
|
||||
else {
|
||||
// this fits exactly the definition for ISO metric fine
|
||||
diameter = diameter - pitch;
|
||||
diameter = diameter - pitch + clearance;
|
||||
}
|
||||
}
|
||||
else { // we have a clearance hole
|
||||
@@ -1058,7 +1205,14 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ThreadFit.setReadOnly(true);
|
||||
ThreadClass.setReadOnly(true);
|
||||
Diameter.setReadOnly(false);
|
||||
ModelThread.setReadOnly(true);
|
||||
UseCustomThreadClearance.setReadOnly(true);
|
||||
CustomThreadClearance.setReadOnly(true);
|
||||
ThreadDepth.setReadOnly(true);
|
||||
ThreadDepthType.setReadOnly(true);
|
||||
Threaded.setValue(0);
|
||||
ModelThread.setValue(0);
|
||||
UseCustomThreadClearance.setValue(0);
|
||||
}
|
||||
else if ( type == "ISOMetricProfile" ) {
|
||||
ThreadSize.setEnums(ThreadSize_ISOmetric_Enums);
|
||||
@@ -1072,6 +1226,11 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ThreadFit.setReadOnly(Threaded.getValue());
|
||||
ThreadClass.setReadOnly(!Threaded.getValue());
|
||||
Diameter.setReadOnly(true);
|
||||
ModelThread.setReadOnly(!Threaded.getValue());
|
||||
UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue());
|
||||
CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue());
|
||||
ThreadDepthType.setReadOnly(!Threaded.getValue());
|
||||
ThreadDepth.setReadOnly(!Threaded.getValue());
|
||||
}
|
||||
else if ( type == "ISOMetricFineProfile" ) {
|
||||
ThreadSize.setEnums(ThreadSize_ISOmetricfine_Enums);
|
||||
@@ -1085,6 +1244,11 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ThreadFit.setReadOnly(Threaded.getValue());
|
||||
ThreadClass.setReadOnly(!Threaded.getValue());
|
||||
Diameter.setReadOnly(true);
|
||||
ModelThread.setReadOnly(!Threaded.getValue());
|
||||
UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue());
|
||||
CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue());
|
||||
ThreadDepthType.setReadOnly(!Threaded.getValue());
|
||||
ThreadDepth.setReadOnly(!Threaded.getValue());
|
||||
}
|
||||
else if ( type == "UNC" ) {
|
||||
ThreadSize.setEnums(ThreadSize_UNC_Enums);
|
||||
@@ -1098,6 +1262,11 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ThreadFit.setReadOnly(Threaded.getValue());
|
||||
ThreadClass.setReadOnly(!Threaded.getValue());
|
||||
Diameter.setReadOnly(true);
|
||||
ModelThread.setReadOnly(!Threaded.getValue());
|
||||
UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue());
|
||||
CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue());
|
||||
ThreadDepthType.setReadOnly(!Threaded.getValue());
|
||||
ThreadDepth.setReadOnly(!Threaded.getValue());
|
||||
}
|
||||
else if ( type == "UNF" ) {
|
||||
ThreadSize.setEnums(ThreadSize_UNF_Enums);
|
||||
@@ -1111,6 +1280,11 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ThreadFit.setReadOnly(Threaded.getValue());
|
||||
ThreadClass.setReadOnly(!Threaded.getValue());
|
||||
Diameter.setReadOnly(true);
|
||||
ModelThread.setReadOnly(!Threaded.getValue());
|
||||
UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue());
|
||||
CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue());
|
||||
ThreadDepthType.setReadOnly(!Threaded.getValue());
|
||||
ThreadDepth.setReadOnly(!Threaded.getValue());
|
||||
}
|
||||
else if ( type == "UNEF" ) {
|
||||
ThreadSize.setEnums(ThreadSize_UNEF_Enums);
|
||||
@@ -1122,8 +1296,13 @@ void Hole::onChanged(const App::Property *prop)
|
||||
// thread class and direction are only sensible if threaded
|
||||
// fit only sensible if not threaded
|
||||
ThreadFit.setReadOnly(Threaded.getValue());
|
||||
ThreadClass.setReadOnly(!Threaded.getValue());;
|
||||
ThreadClass.setReadOnly(!Threaded.getValue());
|
||||
Diameter.setReadOnly(true);
|
||||
ModelThread.setReadOnly(!Threaded.getValue());
|
||||
UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue());
|
||||
CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue());
|
||||
ThreadDepthType.setReadOnly(!Threaded.getValue());
|
||||
ThreadDepth.setReadOnly(!Threaded.getValue());
|
||||
}
|
||||
|
||||
if (holeCutTypeStr == "None") {
|
||||
@@ -1166,12 +1345,6 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ProfileBased::onChanged(&HoleCutType);
|
||||
ProfileBased::onChanged(&Threaded);
|
||||
|
||||
bool v = (type != "None") || !Threaded.getValue() || !ModelActualThread.getValue();
|
||||
ThreadPitch.setReadOnly(v);
|
||||
ThreadAngle.setReadOnly(v);
|
||||
ThreadCutOffInner.setReadOnly(v);
|
||||
ThreadCutOffOuter.setReadOnly(v);
|
||||
|
||||
// Diameter parameter depends on this
|
||||
if (type != "None" )
|
||||
updateDiameterParam();
|
||||
@@ -1185,7 +1358,11 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ThreadClass.setReadOnly(false);
|
||||
ThreadDirection.setReadOnly(false);
|
||||
ThreadFit.setReadOnly(true);
|
||||
ModelActualThread.setReadOnly(true); // For now set this one to read only
|
||||
ModelThread.setReadOnly(false);
|
||||
UseCustomThreadClearance.setReadOnly(false);
|
||||
CustomThreadClearance.setReadOnly(!UseCustomThreadClearance.getValue());
|
||||
ThreadDepthType.setReadOnly(false);
|
||||
ThreadDepth.setReadOnly(std::string(ThreadDepthType.getValueAsString()) != "Dimension");
|
||||
}
|
||||
else {
|
||||
ThreadClass.setReadOnly(true);
|
||||
@@ -1194,21 +1371,20 @@ void Hole::onChanged(const App::Property *prop)
|
||||
ThreadFit.setReadOnly(true);
|
||||
else
|
||||
ThreadFit.setReadOnly(false);
|
||||
ModelActualThread.setReadOnly(true);
|
||||
ModelThread.setReadOnly(true);
|
||||
UseCustomThreadClearance.setReadOnly(true);
|
||||
CustomThreadClearance.setReadOnly(true);
|
||||
ThreadDepthType.setReadOnly(true);
|
||||
ThreadDepth.setReadOnly(true);
|
||||
}
|
||||
|
||||
// Diameter parameter depends on this
|
||||
updateDiameterParam();
|
||||
}
|
||||
else if (prop == &ModelActualThread) {
|
||||
bool v =(!ModelActualThread.getValue()) ||
|
||||
(Threaded.isReadOnly()) ||
|
||||
(std::string(ThreadType.getValueAsString()) != "None");
|
||||
|
||||
ThreadPitch.setReadOnly(v);
|
||||
ThreadAngle.setReadOnly(v);
|
||||
ThreadCutOffInner.setReadOnly(v);
|
||||
ThreadCutOffOuter.setReadOnly(v);
|
||||
else if (prop == &ModelThread) {
|
||||
// Diameter parameter depends on this
|
||||
updateDiameterParam();
|
||||
UseCustomThreadClearance.setReadOnly(!ModelThread.getValue());
|
||||
}
|
||||
else if (prop == &DrillPoint) {
|
||||
if (DrillPoint.getValue() == 1) {
|
||||
@@ -1225,9 +1401,11 @@ void Hole::onChanged(const App::Property *prop)
|
||||
TaperedAngle.setReadOnly(false);
|
||||
else
|
||||
TaperedAngle.setReadOnly(true);
|
||||
|
||||
}
|
||||
else if (prop == &ThreadSize) {
|
||||
updateDiameterParam();
|
||||
updateThreadDepthParam();
|
||||
// updateHoleCutParams() will later automatically be called because updateDiameterParam() changes &Diameter
|
||||
}
|
||||
else if (prop == &ThreadFit) {
|
||||
@@ -1257,7 +1435,28 @@ void Hole::onChanged(const App::Property *prop)
|
||||
DrillPoint.setReadOnly((std::string(DepthType.getValueAsString()) != "Dimension"));
|
||||
DrillPointAngle.setReadOnly((std::string(DepthType.getValueAsString()) != "Dimension"));
|
||||
DrillForDepth.setReadOnly((std::string(DepthType.getValueAsString()) != "Dimension"));
|
||||
updateThreadDepthParam();
|
||||
}
|
||||
else if (prop == &Depth) {
|
||||
if (std::string(ThreadDepthType.getValueAsString()) == "Automatic") {
|
||||
updateDiameterParam(); // make sure diameter and pitch are updated.
|
||||
updateThreadDepthParam();
|
||||
}
|
||||
}
|
||||
else if (prop == &ThreadDepthType) {
|
||||
updateThreadDepthParam();
|
||||
ThreadDepth.setReadOnly(Threaded.getValue() && std::string(ThreadDepthType.getValueAsString()) != "Dimension");
|
||||
}
|
||||
else if (prop == &ThreadDepth) {
|
||||
}
|
||||
else if (prop == &UseCustomThreadClearance) {
|
||||
updateDiameterParam();
|
||||
CustomThreadClearance.setReadOnly(!UseCustomThreadClearance.getValue());
|
||||
}
|
||||
else if (prop == &CustomThreadClearance) {
|
||||
updateDiameterParam();
|
||||
}
|
||||
|
||||
ProfileBased::onChanged(prop);
|
||||
}
|
||||
|
||||
@@ -1317,11 +1516,6 @@ short Hole::mustExecute() const
|
||||
{
|
||||
if ( ThreadType.isTouched() ||
|
||||
Threaded.isTouched() ||
|
||||
ModelActualThread.isTouched() ||
|
||||
ThreadPitch.isTouched() ||
|
||||
ThreadAngle.isTouched() ||
|
||||
ThreadCutOffInner.isTouched() ||
|
||||
ThreadCutOffOuter.isTouched() ||
|
||||
ThreadSize.isTouched() ||
|
||||
ThreadClass.isTouched() ||
|
||||
ThreadFit.isTouched() ||
|
||||
@@ -1336,7 +1530,13 @@ short Hole::mustExecute() const
|
||||
DrillPoint.isTouched() ||
|
||||
DrillPointAngle.isTouched() ||
|
||||
Tapered.isTouched() ||
|
||||
TaperedAngle.isTouched() )
|
||||
TaperedAngle.isTouched() ||
|
||||
ModelThread.isTouched() ||
|
||||
UseCustomThreadClearance.isTouched() ||
|
||||
CustomThreadClearance.isTouched() ||
|
||||
ThreadDepthType.isTouched() ||
|
||||
ThreadDepth.isTouched()
|
||||
)
|
||||
return 1;
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
@@ -1351,11 +1551,6 @@ void Hole::Restore(Base::XMLReader &reader)
|
||||
void Hole::updateProps()
|
||||
{
|
||||
onChanged(&Threaded);
|
||||
onChanged(&ModelActualThread);
|
||||
onChanged(&ThreadPitch);
|
||||
onChanged(&ThreadAngle);
|
||||
onChanged(&ThreadCutOffInner);
|
||||
onChanged(&ThreadCutOffOuter);
|
||||
onChanged(&ThreadType);
|
||||
onChanged(&ThreadSize);
|
||||
onChanged(&ThreadClass);
|
||||
@@ -1372,6 +1567,11 @@ void Hole::updateProps()
|
||||
onChanged(&DrillPointAngle);
|
||||
onChanged(&Tapered);
|
||||
onChanged(&TaperedAngle);
|
||||
onChanged(&ModelThread);
|
||||
onChanged(&UseCustomThreadClearance);
|
||||
onChanged(&CustomThreadClearance);
|
||||
onChanged(&ThreadDepthType);
|
||||
onChanged(&ThreadDepth);
|
||||
}
|
||||
|
||||
static gp_Pnt toPnt(gp_Vec dir)
|
||||
@@ -1447,8 +1647,7 @@ App::DocumentObjectExecReturn *Hole::execute(void)
|
||||
/* FIXME */
|
||||
}
|
||||
else if ( method == "ThroughAll" ) {
|
||||
// Use a large (10m), but finite length
|
||||
length = 1e4;
|
||||
length = getThroughAllLength();
|
||||
}
|
||||
else
|
||||
return new App::DocumentObjectExecReturn("Hole error: Unsupported length specification");
|
||||
@@ -1466,8 +1665,10 @@ App::DocumentObjectExecReturn *Hole::execute(void)
|
||||
holeCutType == "Cheesehead (deprecated)" ||
|
||||
holeCutType == "Cap screw (deprecated)" ||
|
||||
isDynamicCounterbore(threadType, holeCutType));
|
||||
|
||||
double TaperedAngleVal = Tapered.getValue() ? Base::toRadians( TaperedAngle.getValue() ) : Base::toRadians(90.0);
|
||||
double radiusBottom = Diameter.getValue() / 2.0 - length / tan(TaperedAngleVal);
|
||||
|
||||
double radius = Diameter.getValue() / 2.0;
|
||||
double holeCutRadius = HoleCutDiameter.getValue() / 2.0;
|
||||
gp_Pnt firstPoint(0, 0, 0);
|
||||
@@ -1619,64 +1820,134 @@ App::DocumentObjectExecReturn *Hole::execute(void)
|
||||
else
|
||||
return new App::DocumentObjectExecReturn("Hole error: Could not revolve sketch");
|
||||
|
||||
#if 0
|
||||
|
||||
// Make thread
|
||||
if (Threaded.getValue() && ModelThread.getValue()) {
|
||||
bool leftHanded = (bool) ThreadDirection.getValue();
|
||||
|
||||
// Nomenclature and formulae according to Figure 1 of ISO 68-1
|
||||
// this is the same for all metric and UTS threads as stated here:
|
||||
// https://en.wikipedia.org/wiki/File:ISO_and_UTS_Thread_Dimensions.svg
|
||||
// Note that in the ISO standard, Dmaj is called D, which has been followed here.
|
||||
double D = threadDescription[ThreadType.getValue()][ThreadSize.getValue()].diameter; // Major diameter
|
||||
double P = getThreadPitch();
|
||||
double H = sqrt(3) / 2 * P; // Height of fundamental triangle
|
||||
|
||||
double clearance; // clearance to be added on the diameter
|
||||
if (UseCustomThreadClearance.getValue())
|
||||
clearance = CustomThreadClearance.getValue();
|
||||
else
|
||||
clearance = getThreadClassClearance();
|
||||
|
||||
// construct the cross section going counter-clockwise
|
||||
// for graphical explanation of geometrical construction of p1-p6 see:
|
||||
// https://forum.freecadweb.org/viewtopic.php?f=19&t=54284#p466570
|
||||
gp_Pnt p1 = toPnt((D / 2 - 5 * H / 8 + clearance / 2) * xDir + P / 8 * zDir);
|
||||
gp_Pnt p2 = toPnt((D / 2 + clearance / 2) * xDir + 7 * P / 16 * zDir);
|
||||
gp_Pnt p3 = toPnt((D / 2 + clearance / 2) * xDir + 9 * P / 16 * zDir);
|
||||
gp_Pnt p4 = toPnt((D / 2 - 5 * H / 8 + clearance / 2) * xDir + 7 * P / 8 * zDir);
|
||||
gp_Pnt p5 = toPnt(0.9 * (D / 2 - 5 * H / 8) * xDir + 7 * P / 8 * zDir);
|
||||
gp_Pnt p6 = toPnt(0.9 * (D / 2 - 5 * H / 8) * xDir + P / 8 * zDir);
|
||||
|
||||
// This code is work in progress; making threas in OCC is not very easy, so
|
||||
// this work is postponed until later
|
||||
if (ModelActualThread.getValue()) {
|
||||
BRepBuilderAPI_MakeWire mkThreadWire;
|
||||
double z = 0;
|
||||
double d_min = Diameter.getValue() + ThreadCutOffInner.getValue();
|
||||
double d_maj = Diameter.getValue() - ThreadCutOffInner.getValue();
|
||||
int i = 0;
|
||||
|
||||
firstPoint = toPnt(xDir * d_min);
|
||||
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), firstPoint));
|
||||
while (z < length) {
|
||||
double z1 = i * ThreadPitch.getValue() + ThreadPitch.getValue() * 0.1;
|
||||
double z2 = i * ThreadPitch.getValue() + ThreadPitch.getValue() * 0.45;
|
||||
double z3 = i * ThreadPitch.getValue() + ThreadPitch.getValue() * 0.55;
|
||||
double z4 = i * ThreadPitch.getValue() + ThreadPitch.getValue() * 0.9;
|
||||
|
||||
gp_Pnt p2 = toPnt(xDir * d_min - zDir * z1);
|
||||
gp_Pnt p3 = toPnt(xDir * d_maj - zDir * z2);
|
||||
gp_Pnt p4 = toPnt(xDir * d_maj - zDir * z3);
|
||||
gp_Pnt p5 = toPnt(xDir * d_min - zDir * z4);
|
||||
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(firstPoint, p2));
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p2, p3));
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4));
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5));
|
||||
firstPoint = p5;
|
||||
|
||||
++i;
|
||||
z += ThreadPitch.getValue();
|
||||
}
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(firstPoint, toPnt(-z * zDir)));
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(toPnt(-z * zDir), gp_Pnt(0, 0, 0)));
|
||||
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge());
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p2, p3).Edge());
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge());
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge());
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge());
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge());
|
||||
mkThreadWire.Build();
|
||||
TopoDS_Wire threadWire = mkThreadWire.Wire();
|
||||
|
||||
TopoDS_Face threadFace = BRepBuilderAPI_MakeFace(threadWire);
|
||||
|
||||
//TopoDS_Wire helix = TopoShape::makeHelix(ThreadPitch.getValue(), ThreadPitch.getValue(), Diameter.getValue());
|
||||
|
||||
double angle = Base::toRadians<double>(360.0);
|
||||
BRepPrimAPI_MakeRevol RevolMaker2(threadFace, gp_Ax1(gp_Pnt(0,0,0), zDir), angle);
|
||||
|
||||
//TopoDS_Shape protoHole;
|
||||
if (RevolMaker2.IsDone()) {
|
||||
protoHole = RevolMaker2.Shape();
|
||||
|
||||
if (protoHole.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Hole: Resulting shape is empty");
|
||||
//create the helix path
|
||||
double threadDepth = ThreadDepth.getValue();
|
||||
double helixLength = threadDepth + P/2;
|
||||
std::string threadDepthMethod(ThreadDepthType.getValueAsString());
|
||||
if ( threadDepthMethod == "Automatic" ) {
|
||||
std::string depthMethod(DepthType.getValueAsString());
|
||||
if ( depthMethod == "ThroughAll" ) {
|
||||
threadDepth = length;
|
||||
ThreadDepth.setValue(threadDepth);
|
||||
helixLength = threadDepth + 2*P;
|
||||
} else {
|
||||
threadDepth = Depth.getValue() - getThreadRunout();
|
||||
ThreadDepth.setValue(threadDepth);
|
||||
helixLength = threadDepth + P/2;
|
||||
}
|
||||
}
|
||||
else
|
||||
return new App::DocumentObjectExecReturn("Hole: Could not revolve sketch!");
|
||||
TopoDS_Shape helix = TopoShape().makeLongHelix(P, helixLength, D / 2, 0.0, leftHanded);
|
||||
|
||||
gp_Pnt origo(0.0, 0.0, 0.0);
|
||||
gp_Dir dir_axis1(0.0, 0.0, 1.0); // pointing along the helix axis, as created.
|
||||
gp_Dir dir_axis2(1.0, 0.0, 0.0); // pointing towards the helix start point, as created.
|
||||
|
||||
// Reverse the direction of the helix. So that it goes into the material
|
||||
gp_Trsf mov;
|
||||
mov.SetRotation(gp_Ax1(origo, dir_axis2), M_PI);
|
||||
TopLoc_Location loc1(mov);
|
||||
helix.Move(loc1);
|
||||
|
||||
// rotate the helix so that it is pointing in the zdir.
|
||||
double angle = acos(dir_axis1*zDir);
|
||||
if (abs(angle) > Precision::Confusion()) {
|
||||
gp_Dir rotAxis = dir_axis1^zDir;
|
||||
mov.SetRotation(gp_Ax1(origo, rotAxis), angle);
|
||||
TopLoc_Location loc2(mov);
|
||||
helix.Move(loc2);
|
||||
}
|
||||
|
||||
// create the pipe shell
|
||||
BRepOffsetAPI_MakePipeShell mkPS(TopoDS::Wire(helix));
|
||||
mkPS.SetTolerance(Precision::Confusion());
|
||||
mkPS.SetTransitionMode(BRepBuilderAPI_Transformed);
|
||||
mkPS.SetMode(true); //This is for frenet
|
||||
mkPS.Add(threadWire);
|
||||
if (!mkPS.IsReady())
|
||||
return new App::DocumentObjectExecReturn("Error: Thread could not be built");
|
||||
TopoDS_Shape shell = mkPS.Shape();
|
||||
|
||||
// create faces at the ends of the pipe shell
|
||||
TopTools_ListOfShape sim;
|
||||
mkPS.Simulate(2, sim);
|
||||
std::vector<TopoDS_Wire> frontwires, backwires;
|
||||
frontwires.push_back(TopoDS::Wire(sim.First()));
|
||||
backwires.push_back(TopoDS::Wire(sim.Last()));
|
||||
// build the end faces
|
||||
TopoDS_Shape front = Part::FaceMakerCheese::makeFace(frontwires);
|
||||
TopoDS_Shape back = Part::FaceMakerCheese::makeFace(backwires);
|
||||
|
||||
// sew the shell and end faces
|
||||
BRepBuilderAPI_Sewing sewer;
|
||||
sewer.SetTolerance(Precision::Confusion());
|
||||
sewer.Add(front);
|
||||
sewer.Add(back);
|
||||
sewer.Add(shell);
|
||||
sewer.Perform();
|
||||
|
||||
// make the closed off shell into a solid
|
||||
BRepBuilderAPI_MakeSolid mkSolid;
|
||||
mkSolid.Add(TopoDS::Shell(sewer.SewedShape()));
|
||||
if(!mkSolid.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Error: Result is not a solid");
|
||||
TopoDS_Shape result = mkSolid.Shape();
|
||||
|
||||
// check if the algorithm has confused the inside and outside of the solid
|
||||
BRepClass3d_SolidClassifier SC(result);
|
||||
SC.PerformInfinitePoint(Precision::Confusion());
|
||||
if (SC.State() == TopAbs_IN)
|
||||
result.Reverse();
|
||||
|
||||
// we are done
|
||||
TopoDS_Shape protoThread = result;
|
||||
|
||||
// fuse the thread to the hole
|
||||
BRepAlgoAPI_Fuse mkFuse(protoHole, protoThread);
|
||||
if (!mkFuse.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Error: Adding the thread failed");
|
||||
|
||||
// we reuse the name protoHole (only now it is threaded)
|
||||
protoHole = mkFuse.Shape();
|
||||
}
|
||||
#endif
|
||||
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound holes;
|
||||
@@ -1739,6 +2010,7 @@ App::DocumentObjectExecReturn *Hole::execute(void)
|
||||
|
||||
remapSupportShape(base);
|
||||
|
||||
|
||||
int solidCount = countSolids(base);
|
||||
if (solidCount > 1) {
|
||||
return new App::DocumentObjectExecReturn("Hole: Result has multiple solids. This is not supported at this time.");
|
||||
|
||||
@@ -37,6 +37,9 @@ class XMLReader;
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
static constexpr size_t ThreadClass_ISOmetric_data_size = 25;
|
||||
static constexpr size_t ThreadRunout_size = 24;
|
||||
|
||||
class PartDesignExport Hole : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Hole);
|
||||
@@ -45,11 +48,8 @@ public:
|
||||
Hole();
|
||||
|
||||
App::PropertyBool Threaded;
|
||||
App::PropertyBool ModelActualThread;
|
||||
App::PropertyBool ModelThread;
|
||||
App::PropertyLength ThreadPitch;
|
||||
App::PropertyAngle ThreadAngle;
|
||||
App::PropertyLength ThreadCutOffInner;
|
||||
App::PropertyLength ThreadCutOffOuter;
|
||||
App::PropertyEnumeration ThreadType;
|
||||
App::PropertyEnumeration ThreadSize;
|
||||
App::PropertyEnumeration ThreadClass;
|
||||
@@ -63,11 +63,15 @@ public:
|
||||
App::PropertyAngle HoleCutCountersinkAngle;
|
||||
App::PropertyEnumeration DepthType;
|
||||
App::PropertyLength Depth;
|
||||
App::PropertyEnumeration ThreadDepthType;
|
||||
App::PropertyLength ThreadDepth;
|
||||
App::PropertyEnumeration DrillPoint;
|
||||
App::PropertyAngle DrillPointAngle;
|
||||
App::PropertyBool DrillForDepth;
|
||||
App::PropertyBool Tapered;
|
||||
App::PropertyAngle TaperedAngle;
|
||||
App::PropertyBool UseCustomThreadClearance;
|
||||
App::PropertyLength CustomThreadClearance;
|
||||
|
||||
/** @name methods override feature */
|
||||
//@{
|
||||
@@ -107,6 +111,7 @@ protected:
|
||||
void onChanged(const App::Property* prop);
|
||||
private:
|
||||
static const char* DepthTypeEnums[];
|
||||
static const char* ThreadDepthTypeEnums[];
|
||||
static const char* ThreadTypeEnums[];
|
||||
static const char* ClearanceMetricEnums[];
|
||||
static const char* ClearanceUTSEnums[];
|
||||
@@ -122,6 +127,7 @@ private:
|
||||
static std::vector<std::string> HoleCutType_ISOmetric_Enums;
|
||||
static const char* ThreadSize_ISOmetric_Enums[];
|
||||
static const char* ThreadClass_ISOmetric_Enums[];
|
||||
static const double ThreadClass_ISOmetric_data[ThreadClass_ISOmetric_data_size][2];
|
||||
|
||||
/* ISO metric fine profile */
|
||||
static std::vector<std::string> HoleCutType_ISOmetricfine_Enums;
|
||||
@@ -143,6 +149,8 @@ private:
|
||||
static const char* ThreadSize_UNEF_Enums[];
|
||||
static const char* ThreadClass_UNEF_Enums[];
|
||||
|
||||
static const double ThreadRunout[ThreadRunout_size][2];
|
||||
|
||||
/* Counter-xxx */
|
||||
//public:
|
||||
// Dimension for counterbore
|
||||
@@ -203,8 +211,13 @@ private:
|
||||
bool isDynamicCountersink(const std::string &thread, const std::string &holeCutType);
|
||||
void updateHoleCutParams();
|
||||
void updateDiameterParam();
|
||||
void updateThreadDepthParam();
|
||||
void readCutDefinitions();
|
||||
|
||||
double getThreadClassClearance();
|
||||
double getThreadRunout(int mode = 1);
|
||||
double getThreadPitch();
|
||||
|
||||
// helpers for nlohmann json
|
||||
friend void from_json(const nlohmann::json &j, CounterBoreDimension &t);
|
||||
friend void from_json(const nlohmann::json &j, CounterSinkDimension &t);
|
||||
|
||||
@@ -76,8 +76,12 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare
|
||||
|
||||
// read values from the hole properties
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
ui->Threaded->setChecked(pcHole->Threaded.getValue());
|
||||
ui->Threaded->setDisabled(std::string(pcHole->ThreadType.getValueAsString()) == "None");
|
||||
|
||||
ui->ThreadType->setCurrentIndex(pcHole->ThreadType.getValue());
|
||||
|
||||
ui->ThreadSize->clear();
|
||||
const char** cursor = pcHole->ThreadSize.getEnums();
|
||||
while (*cursor) {
|
||||
@@ -162,6 +166,22 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare
|
||||
ui->TaperedAngle->setValue(pcHole->TaperedAngle.getValue());
|
||||
ui->Reversed->setChecked(pcHole->Reversed.getValue());
|
||||
|
||||
ui->ModelThread->setChecked(pcHole->ModelThread.getValue());
|
||||
ui->UseCustomThreadClearance->setChecked(pcHole->UseCustomThreadClearance.getValue());
|
||||
ui->CustomThreadClearance->setValue(pcHole->CustomThreadClearance.getValue());
|
||||
ui->ThreadDepthType->setCurrentIndex(pcHole->ThreadDepthType.getValue());
|
||||
ui->ThreadDepth->setValue(pcHole->ThreadDepth.getValue());
|
||||
|
||||
// conditional enabling of thread modeling options
|
||||
ui->ModelThread->setEnabled(ui->Threaded->isChecked() && ui->ThreadType->currentIndex() != 0);
|
||||
ui->UseCustomThreadClearance->setEnabled(ui->Threaded->isChecked() && ui->ModelThread->isChecked());
|
||||
ui->labelThreadClearance->setEnabled(ui->Threaded->isChecked() && ui->ModelThread->isChecked() && ui->UseCustomThreadClearance->isChecked());
|
||||
ui->CustomThreadClearance->setEnabled(ui->Threaded->isChecked() && ui->ModelThread->isChecked() && ui->UseCustomThreadClearance->isChecked());
|
||||
ui->UpdateView->setChecked(!ui->ModelThread->isChecked());
|
||||
|
||||
ui->ThreadDepthType->setEnabled(ui->Threaded->isChecked());
|
||||
ui->ThreadDepth->setEnabled(ui->Threaded->isChecked() && std::string(pcHole->ThreadDepthType.getValueAsString()) == "Dimension");
|
||||
|
||||
connect(ui->Threaded, SIGNAL(clicked(bool)), this, SLOT(threadedChanged()));
|
||||
connect(ui->ThreadType, SIGNAL(currentIndexChanged(int)), this, SLOT(threadTypeChanged(int)));
|
||||
connect(ui->ThreadSize, SIGNAL(currentIndexChanged(int)), this, SLOT(threadSizeChanged(int)));
|
||||
@@ -184,6 +204,12 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare
|
||||
connect(ui->Tapered, SIGNAL(clicked(bool)), this, SLOT(taperedChanged()));
|
||||
connect(ui->Reversed, SIGNAL(clicked(bool)), this, SLOT(reversedChanged()));
|
||||
connect(ui->TaperedAngle, SIGNAL(valueChanged(double)), this, SLOT(taperedAngleChanged(double)));
|
||||
connect(ui->ModelThread, SIGNAL(clicked(bool)), this, SLOT(modelThreadChanged()));
|
||||
connect(ui->UpdateView, SIGNAL(toggled(bool)), this, SLOT(updateViewChanged(bool)));
|
||||
connect(ui->UseCustomThreadClearance, SIGNAL(toggled(bool)), this, SLOT(useCustomThreadClearanceChanged()));
|
||||
connect(ui->CustomThreadClearance, SIGNAL(valueChanged(double)), this, SLOT(customThreadClearanceChanged(double)));
|
||||
connect(ui->ThreadDepthType, SIGNAL(currentIndexChanged(int)), this, SLOT(threadDepthTypeChanged(int)));
|
||||
connect(ui->ThreadDepth, SIGNAL(valueChanged(double)), this, SLOT(threadDepthChanged(double)));
|
||||
|
||||
vp->show();
|
||||
|
||||
@@ -194,6 +220,8 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare
|
||||
ui->Depth->bind(pcHole->Depth);
|
||||
ui->DrillPointAngle->bind(pcHole->DrillPointAngle);
|
||||
ui->TaperedAngle->bind(pcHole->TaperedAngle);
|
||||
ui->ThreadDepth->bind(pcHole->ThreadDepth);
|
||||
ui->CustomThreadClearance->bind(pcHole->CustomThreadClearance);
|
||||
|
||||
connectPropChanged = App::GetApplication().signalChangePropertyEditor.connect(
|
||||
boost::bind(&TaskHoleParameters::changedObject, this, bp::_1, bp::_2));
|
||||
@@ -209,15 +237,83 @@ void TaskHoleParameters::threadedChanged()
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
bool isChecked = ui->Threaded->isChecked();
|
||||
pcHole->Threaded.setValue(isChecked);
|
||||
|
||||
ui->ModelThread->setEnabled(isChecked);
|
||||
ui->ThreadDepthType->setEnabled(isChecked);
|
||||
|
||||
// conditional enabling of thread modeling options
|
||||
ui->UseCustomThreadClearance->setEnabled(ui->Threaded->isChecked() && ui->ModelThread->isChecked());
|
||||
ui->CustomThreadClearance->setEnabled(ui->Threaded->isChecked() && ui->ModelThread->isChecked() && ui->UseCustomThreadClearance->isChecked());
|
||||
|
||||
updateViewChanged(!(isChecked && ui->ModelThread->isChecked()));
|
||||
ui->UpdateView->setChecked(!(isChecked && ui->ModelThread->isChecked()));
|
||||
|
||||
pcHole->Threaded.setValue(ui->Threaded->isChecked());
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::modelActualThreadChanged()
|
||||
void TaskHoleParameters::modelThreadChanged()
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
bool isChecked = ui->ModelThread->isChecked();
|
||||
|
||||
pcHole->ModelThread.setValue(isChecked);
|
||||
|
||||
// update view not active if modeling threads
|
||||
// this will also ensure that the feature is recomputed.
|
||||
blockUpdate = isChecked;
|
||||
ui->UpdateView->setChecked(!isChecked);
|
||||
|
||||
// conditional enabling of thread modeling options
|
||||
ui->UseCustomThreadClearance->setEnabled(ui->Threaded->isChecked() && ui->ModelThread->isChecked());
|
||||
ui->CustomThreadClearance->setEnabled(ui->Threaded->isChecked() && ui->ModelThread->isChecked() && ui->UseCustomThreadClearance->isChecked());
|
||||
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::updateViewChanged(bool isChecked)
|
||||
{
|
||||
blockUpdate = !isChecked;
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::threadDepthTypeChanged(int index)
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
pcHole->ModelActualThread.setValue(false);
|
||||
pcHole->ThreadDepthType.setValue(index);
|
||||
ui->ThreadDepth->setEnabled(index == 1);
|
||||
ui->ThreadDepth->setValue(pcHole->ThreadDepth.getValue());
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::threadDepthChanged(double value)
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
pcHole->ThreadDepth.setValue(value);
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::useCustomThreadClearanceChanged()
|
||||
{
|
||||
bool isChecked = ui->UseCustomThreadClearance->isChecked();
|
||||
ui->CustomThreadClearance->setEnabled(isChecked);
|
||||
ui->ThreadClass->setDisabled(isChecked);
|
||||
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
pcHole->UseCustomThreadClearance.setValue(isChecked);
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::customThreadClearanceChanged(double value)
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
pcHole->CustomThreadClearance.setValue(value);
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
@@ -229,30 +325,6 @@ void TaskHoleParameters::threadPitchChanged(double value)
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::threadAngleChanged(double value)
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
pcHole->ThreadAngle.setValue(value);
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::threadCutOffInnerChanged(double value)
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
pcHole->ThreadCutOffInner.setValue(value);
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::threadCutOffOuterChanged(double value)
|
||||
{
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
pcHole->ThreadCutOffOuter.setValue(value);
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::holeCutTypeChanged(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
@@ -261,7 +333,7 @@ void TaskHoleParameters::holeCutTypeChanged(int index)
|
||||
PartDesign::Hole* pcHole = static_cast<PartDesign::Hole*>(vp->getObject());
|
||||
|
||||
// the HoleCutDepth is something different for countersinks and counterbores
|
||||
// therefore reset it, it will be reset to sensible values by setting the new HoleCutType
|
||||
// therefore reset it, it will be reset to sensible values by setting the new HoleCutType
|
||||
pcHole->HoleCutDepth.setValue(0.0);
|
||||
|
||||
// when holeCutType was changed, reset HoleCutCustomValues to false because it should
|
||||
@@ -280,7 +352,7 @@ void TaskHoleParameters::holeCutTypeChanged(int index)
|
||||
ui->HoleCutCustomValues->setChecked(pcHole->HoleCutCustomValues.getValue());
|
||||
|
||||
// HoleCutCustomValues is only enabled for screw definitions
|
||||
// we must do this after recomputeFeature() because this gives us the info if
|
||||
// we must do this after recomputeFeature() because this gives us the info if
|
||||
// the type is a countersink and thus if HoleCutCountersinkAngle can be enabled
|
||||
std::string HoleCutTypeString = pcHole->HoleCutType.getValueAsString();
|
||||
if (HoleCutTypeString == "None" || HoleCutTypeString == "Counterbore"
|
||||
@@ -322,7 +394,7 @@ void TaskHoleParameters::holeCutCustomValuesChanged()
|
||||
ui->HoleCutCountersinkAngle->setEnabled(false);
|
||||
}
|
||||
|
||||
recomputeFeature();
|
||||
recomputeFeature();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::holeCutDiameterChanged(double value)
|
||||
@@ -479,11 +551,14 @@ void TaskHoleParameters::threadTypeChanged(int index)
|
||||
// now set the new type, this will reset the comboboxes to item 0
|
||||
pcHole->ThreadType.setValue(index);
|
||||
|
||||
// Threaded checkbox is meaningless if no thread profile is selected.
|
||||
ui->Threaded->setDisabled(std::string(pcHole->ThreadType.getValueAsString()) == "None");
|
||||
|
||||
// size and clearance
|
||||
if (TypeClass == QByteArray("ISO")) {
|
||||
// the size for ISO type has either the form "M3x0.35" or just "M3"
|
||||
// so we need to check if the size contains a 'x'. If yes, check if the string
|
||||
// up to the 'x' is exists in the new list
|
||||
// up to the 'x' is exists in the new list
|
||||
if (ThreadSizeString.indexOf(QString::fromLatin1("x")) > -1) {
|
||||
// we have an ISO fine size
|
||||
// cut of the part behind the 'x'
|
||||
@@ -499,7 +574,7 @@ void TaskHoleParameters::threadTypeChanged(int index)
|
||||
ui->ThreadFit->setItemText(0, QCoreApplication::translate("TaskHoleParameters", "Standard", nullptr));
|
||||
ui->ThreadFit->setItemText(1, QCoreApplication::translate("TaskHoleParameters", "Close", nullptr));
|
||||
ui->ThreadFit->setItemText(2, QCoreApplication::translate("TaskHoleParameters", "Wide", nullptr));
|
||||
}
|
||||
}
|
||||
else if (TypeClass == QByteArray("UTS")) {
|
||||
// for all UTS types the size entries are the same
|
||||
int threadSizeIndex = ui->ThreadSize->findText(ThreadSizeString, Qt::MatchContains);
|
||||
@@ -813,6 +888,51 @@ void TaskHoleParameters::changedObject(const App::Document&, const App::Property
|
||||
}
|
||||
ui->TaperedAngle->setDisabled(ro);
|
||||
}
|
||||
else if (&Prop == &pcHole->ModelThread) {
|
||||
ui->ModelThread->setEnabled(true);
|
||||
if (ui->ModelThread->isChecked() ^ pcHole->ModelThread.getValue()) {
|
||||
ui->ModelThread->blockSignals(true);
|
||||
ui->ModelThread->setChecked(pcHole->ModelThread.getValue());
|
||||
ui->ModelThread->blockSignals(false);
|
||||
}
|
||||
ui->ModelThread->setDisabled(ro);
|
||||
}
|
||||
else if (&Prop == &pcHole->UseCustomThreadClearance) {
|
||||
ui->UseCustomThreadClearance->setEnabled(true);
|
||||
if (ui->UseCustomThreadClearance->isChecked() ^ pcHole->UseCustomThreadClearance.getValue()) {
|
||||
ui->UseCustomThreadClearance->blockSignals(true);
|
||||
ui->UseCustomThreadClearance->setChecked(pcHole->UseCustomThreadClearance.getValue());
|
||||
ui->UseCustomThreadClearance->blockSignals(false);
|
||||
}
|
||||
ui->UseCustomThreadClearance->setDisabled(ro);
|
||||
}
|
||||
else if (&Prop == &pcHole->CustomThreadClearance) {
|
||||
ui->CustomThreadClearance->setEnabled(true);
|
||||
if (ui->CustomThreadClearance->value().getValue() != pcHole->CustomThreadClearance.getValue()) {
|
||||
ui->CustomThreadClearance->blockSignals(true);
|
||||
ui->CustomThreadClearance->setValue(pcHole->CustomThreadClearance.getValue());
|
||||
ui->CustomThreadClearance->blockSignals(false);
|
||||
}
|
||||
ui->CustomThreadClearance->setDisabled(ro);
|
||||
}
|
||||
else if (&Prop == &pcHole->ThreadDepthType) {
|
||||
ui->ThreadDepthType->setEnabled(true);
|
||||
if (ui->ThreadDepthType->currentIndex() != pcHole->ThreadDepthType.getValue()) {
|
||||
ui->ThreadDepthType->blockSignals(true);
|
||||
ui->ThreadDepthType->setCurrentIndex(pcHole->ThreadDepthType.getValue());
|
||||
ui->ThreadDepthType->blockSignals(false);
|
||||
}
|
||||
ui->ThreadDepthType->setDisabled(ro);
|
||||
}
|
||||
else if (&Prop == &pcHole->ThreadDepth) {
|
||||
ui->ThreadDepth->setEnabled(true);
|
||||
if (ui->ThreadDepth->value().getValue() != pcHole->ThreadDepth.getValue()) {
|
||||
ui->ThreadDepth->blockSignals(true);
|
||||
ui->ThreadDepth->setValue(pcHole->ThreadDepth.getValue());
|
||||
ui->ThreadDepth->blockSignals(false);
|
||||
}
|
||||
ui->ThreadDepth->setDisabled(ro);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskHoleParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
@@ -934,6 +1054,31 @@ Base::Quantity TaskHoleParameters::getTaperedAngle() const
|
||||
return ui->TaperedAngle->value();
|
||||
}
|
||||
|
||||
bool TaskHoleParameters::getUseCustomThreadClearance() const
|
||||
{
|
||||
return ui->UseCustomThreadClearance->isChecked();
|
||||
}
|
||||
|
||||
double TaskHoleParameters::getCustomThreadClearance() const
|
||||
{
|
||||
return ui->CustomThreadClearance->value().getValue();
|
||||
}
|
||||
|
||||
bool TaskHoleParameters::getModelThread() const
|
||||
{
|
||||
return ui->ModelThread->isChecked();
|
||||
}
|
||||
|
||||
long TaskHoleParameters::getThreadDepthType() const
|
||||
{
|
||||
return ui->ThreadDepthType->currentIndex();
|
||||
}
|
||||
|
||||
double TaskHoleParameters::getThreadDepth() const
|
||||
{
|
||||
return ui->ThreadDepth->value().getValue();
|
||||
}
|
||||
|
||||
void TaskHoleParameters::apply()
|
||||
{
|
||||
auto obj = vp->getObject();
|
||||
@@ -951,15 +1096,23 @@ void TaskHoleParameters::apply()
|
||||
|
||||
if (!pcHole->Threaded.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"Threaded = " << (getThreaded() ? 1 : 0));
|
||||
if (!pcHole->ModelActualThread.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ModelActualThread = " << (getThreaded() ? 1 : 0));
|
||||
if (!pcHole->ModelThread.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ModelThread = " << (getModelThread() ? 1 : 0));
|
||||
if (!pcHole->ThreadDepthType.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ThreadDepthType = " << getThreadDepthType());
|
||||
if (!pcHole->ThreadDepth.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ThreadDepth = " << getThreadDepth());
|
||||
if (!pcHole->UseCustomThreadClearance.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"UseCustomThreadClearance = " << (getUseCustomThreadClearance() ? 1 : 0) );
|
||||
if (!pcHole->CustomThreadClearance.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"CustomThreadClearance = " << getCustomThreadClearance());
|
||||
if (!pcHole->ThreadType.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ThreadType = " << getThreadType());
|
||||
if (!pcHole->ThreadSize.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ThreadSize = " << getThreadSize());
|
||||
if (!pcHole->ThreadClass.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ThreadClass = " << getThreadClass());
|
||||
if (!pcHole->ThreadFit.isReadOnly())
|
||||
if (!pcHole->ThreadFit.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ThreadFit = " << getThreadFit());
|
||||
if (!pcHole->ThreadDirection.isReadOnly())
|
||||
FCMD_OBJ_CMD(obj,"ThreadDirection = " << getThreadDirection());
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace PartDesign {
|
||||
class Hole;
|
||||
}
|
||||
|
||||
namespace PartDesignGui {
|
||||
namespace PartDesignGui {
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class TaskHoleParameters : public TaskSketchBasedParameters
|
||||
public:
|
||||
TaskHoleParameters(ViewProviderHole *HoleView, QWidget *parent = 0);
|
||||
~TaskHoleParameters();
|
||||
|
||||
|
||||
void apply() override;
|
||||
|
||||
bool getThreaded() const;
|
||||
@@ -80,6 +80,11 @@ public:
|
||||
bool getDrillForDepth() const;
|
||||
bool getTapered() const;
|
||||
Base::Quantity getTaperedAngle() const;
|
||||
bool getUseCustomThreadClearance() const;
|
||||
double getCustomThreadClearance() const;
|
||||
bool getModelThread() const;
|
||||
long getThreadDepthType() const;
|
||||
double getThreadDepth() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void threadedChanged();
|
||||
@@ -87,11 +92,7 @@ private Q_SLOTS:
|
||||
void threadSizeChanged(int index);
|
||||
void threadClassChanged(int index);
|
||||
void threadFitChanged(int index);
|
||||
void modelActualThreadChanged();
|
||||
void threadPitchChanged(double value);
|
||||
void threadCutOffOuterChanged(double value);
|
||||
void threadCutOffInnerChanged(double value);
|
||||
void threadAngleChanged(double value);
|
||||
void threadDiameterChanged(double value);
|
||||
void threadDirectionChanged();
|
||||
void holeCutTypeChanged(int index);
|
||||
@@ -105,8 +106,15 @@ private Q_SLOTS:
|
||||
void drillPointAngledValueChanged(double value);
|
||||
void drillForDepthChanged();
|
||||
void taperedChanged();
|
||||
void taperedAngleChanged(double value);
|
||||
void reversedChanged();
|
||||
void taperedAngleChanged(double value);
|
||||
void modelThreadChanged();
|
||||
void useCustomThreadClearanceChanged();
|
||||
void customThreadClearanceChanged(double value);
|
||||
void updateViewChanged(bool isChecked);
|
||||
void threadDepthTypeChanged(int index);
|
||||
void threadDepthChanged(double value);
|
||||
|
||||
private:
|
||||
class Observer : public App::DocumentObserver {
|
||||
public:
|
||||
|
||||
@@ -72,7 +72,91 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="ModelThread">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Whether the hole gets a modelled thread</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Model Thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3" colspan="2">
|
||||
<widget class="QCheckBox" name="UpdateView">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Live update of changes to the thread
|
||||
Note that the calculation can take some time</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Update view</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="UseCustomThreadClearance">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Customize thread clearance</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom Thread Clearance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2" colspan="2">
|
||||
<widget class="QLabel" name="labelThreadClearance">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clearance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="CustomThreadClearance">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Custom Thread clearance value</string>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -88,7 +172,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QRadioButton" name="directionRightHand">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -107,7 +191,7 @@
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="QRadioButton" name="directionLeftHand">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -123,7 +207,7 @@
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -136,7 +220,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QComboBox" name="ThreadSize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -152,7 +236,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -165,7 +249,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="4">
|
||||
<item row="8" column="4">
|
||||
<widget class="QComboBox" name="ThreadFit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -200,7 +284,7 @@ Only available for holes without thread</string>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -213,7 +297,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QComboBox" name="ThreadClass">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -232,7 +316,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2" colspan="2">
|
||||
<item row="9" column="2" colspan="2">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -245,7 +329,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="4">
|
||||
<item row="9" column="4">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="Diameter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -270,7 +354,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -283,7 +367,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QComboBox" name="DepthType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -309,7 +393,7 @@ Only available for holes without thread</string>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2" colspan="3">
|
||||
<item row="10" column="2" colspan="3">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="Depth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -322,14 +406,66 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="labelThreadDepth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Thread Depth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QComboBox" name="ThreadDepthType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Dimension</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2" colspan="3">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="ThreadDepth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string><b>Hole cut</b></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -342,7 +478,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1" colspan="4">
|
||||
<item row="13" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="HoleCutType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -361,7 +497,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="14" column="1">
|
||||
<widget class="QCheckBox" name="HoleCutCustomValues">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -377,7 +513,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<item row="15" column="1">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -390,7 +526,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="2" colspan="3">
|
||||
<item row="15" column="2" colspan="3">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="HoleCutDiameter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -418,7 +554,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<item row="16" column="1">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -431,7 +567,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2" colspan="3">
|
||||
<item row="16" column="2" colspan="3">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="HoleCutDepth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -456,7 +592,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<item row="17" column="1">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -469,7 +605,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2" colspan="3">
|
||||
<item row="17" column="2" colspan="3">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="HoleCutCountersinkAngle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -491,7 +627,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -507,7 +643,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<item row="19" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -523,7 +659,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<item row="19" column="1">
|
||||
<widget class="QRadioButton" name="drillPointFlat">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -539,7 +675,7 @@ Only available for holes without thread</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="1">
|
||||
<item row="22" column="1">
|
||||
<widget class="QRadioButton" name="drillPointAngled">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -555,7 +691,7 @@ Only available for holes without thread</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="2" colspan="3">
|
||||
<item row="22" column="2" colspan="3">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="DrillPointAngle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -571,7 +707,7 @@ Only available for holes without thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="2" colspan="3">
|
||||
<item row="23" column="2" colspan="3">
|
||||
<widget class="QCheckBox" name="DrillForDepth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -588,14 +724,14 @@ account for the depth of blind holes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="0">
|
||||
<item row="24" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string><b>Misc</b></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="22" column="0">
|
||||
<item row="25" column="0">
|
||||
<widget class="QCheckBox" name="Tapered">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -608,7 +744,7 @@ account for the depth of blind holes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="22" column="1">
|
||||
<item row="25" column="1">
|
||||
<widget class="Gui::PrefQuantitySpinBox" name="TaperedAngle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -630,7 +766,7 @@ over 90: larger hole radius at the bottom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="22" column="3" colspan="2">
|
||||
<item row="25" column="3" colspan="2">
|
||||
<widget class="QCheckBox" name="Reversed">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
|
||||
Reference in New Issue
Block a user