|
 |
911124 |
|
|
 |
911124 |
#include <tools assistant.h=""></tools>
|
|
 |
911124 |
|
|
 |
9cf8be |
#include <tgl.h></tgl.h>
|
|
 |
3bac66 |
#include <tproperty.h></tproperty.h>
|
|
 |
9cf8be |
|
|
 |
911124 |
#include <limits></limits>
|
|
 |
c5e805 |
#include <cassert></cassert>
|
|
 |
911124 |
|
|
 |
e48ced |
#ifdef MACOSX
|
|
 |
e48ced |
const double line_width_scale = 1.5;
|
|
 |
e48ced |
#else
|
|
 |
e48ced |
const double line_width_scale = 1.0;
|
|
 |
e48ced |
#endif
|
|
 |
911124 |
|
|
 |
911124 |
//************************************************************************
|
|
 |
911124 |
|
|
 |
911124 |
//************************************************************************
|
|
 |
911124 |
|
|
 |
4df9cd |
void
|
|
 |
8074a5 |
TGuideline::drawSegment(
|
|
 |
8074a5 |
const TPointD &p0,
|
|
 |
8074a5 |
const TPointD &p1,
|
|
 |
8074a5 |
double pixelSize,
|
|
 |
8074a5 |
bool active,
|
|
 |
8074a5 |
bool enabled ) const
|
|
 |
8074a5 |
{
|
|
 |
dba7b5 |
double colorBlack[4] = { 0.0, 0.0, 0.0, 0.25 };
|
|
 |
dba7b5 |
double colorWhite[4] = { 1.0, 1.0, 1.0, 0.25 };
|
|
 |
8074a5 |
|
|
 |
8074a5 |
if (!this->enabled || !enabled)
|
|
 |
dba7b5 |
colorBlack[3] = (colorWhite[3] = 0.125);
|
|
 |
dba7b5 |
else if (active)
|
|
 |
dba7b5 |
colorBlack[3] = (colorWhite[3] = 0.5);
|
|
 |
4df9cd |
|
|
 |
4df9cd |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
 |
4df9cd |
tglEnableBlending();
|
|
 |
e48ced |
tglEnableLineSmooth(true, 1.0 * line_width_scale);
|
|
 |
4df9cd |
TPointD d = p1 - p0;
|
|
 |
4df9cd |
double k = norm2(d);
|
|
 |
4df9cd |
if (k > TConsts::epsilon*TConsts::epsilon) {
|
|
 |
e48ced |
k = 0.5*pixelSize*line_width_scale/sqrt(k);
|
|
 |
4df9cd |
d = TPointD(-k*d.y, k*d.x);
|
|
 |
4df9cd |
glColor4dv(colorWhite);
|
|
 |
4df9cd |
tglDrawSegment(p0 - d, p1 - d);
|
|
 |
4df9cd |
glColor4dv(colorBlack);
|
|
 |
4df9cd |
tglDrawSegment(p0 + d, p1 + d);
|
|
 |
4df9cd |
}
|
|
 |
4df9cd |
glPopAttrib();
|
|
 |
4df9cd |
}
|
|
 |
4df9cd |
|
|
 |
4df9cd |
|
|
 |
4df9cd |
|
|
 |
911124 |
double
|
|
 |
9cf8be |
TGuideline::calcTrackWeight(const TTrack &track, const TAffine &toScreen, bool &outLongEnough) const {
|
|
 |
9cf8be |
outLongEnough = false;
|
|
 |
8074a5 |
if (!enabled || track.size() < 2)
|
|
 |
911124 |
return std::numeric_limits<double>::infinity();</double>
|
|
 |
911124 |
|
|
 |
911124 |
const double snapLenght = 20.0;
|
|
 |
911124 |
const double snapScale = 1.0;
|
|
 |
362052 |
const double maxLength = 2.0*snapLenght*snapScale;
|
|
 |
911124 |
|
|
 |
911124 |
double sumWeight = 0.0;
|
|
 |
911124 |
double sumLength = 0.0;
|
|
 |
911124 |
double sumDeviation = 0.0;
|
|
 |
911124 |
|
|
 |
9cf8be |
TPointD prev = toScreen*track[0].position;
|
|
 |
0abdef |
for(int i = 1; i < track.size(); ++i) {
|
|
 |
911124 |
const TTrackPoint &tp = track[i];
|
|
 |
0abdef |
TTrackPoint mid = TTrack::interpolationLinear(track[i-1], track[i], 0.5);
|
|
 |
9cf8be |
TPointD p = toScreen*tp.position;
|
|
 |
911124 |
double length = tdistance(p, prev);
|
|
 |
911124 |
sumLength += length;
|
|
 |
911124 |
|
|
 |
911124 |
double midStepLength = sumLength - 0.5*length;
|
|
 |
9f0c16 |
if (midStepLength > TConsts::epsilon) {
|
|
 |
911124 |
double weight = length*logNormalDistribuitionUnscaled(midStepLength, snapLenght, snapScale);
|
|
 |
911124 |
sumWeight += weight;
|
|
 |
911124 |
|
|
 |
52242c |
TPointD ntp = nearestPoint(mid.position);
|
|
 |
52242c |
double deviation = tdistance(toScreen*ntp, p);
|
|
 |
911124 |
sumDeviation += weight*deviation;
|
|
 |
911124 |
}
|
|
 |
911124 |
prev = p;
|
|
 |
9cf8be |
|
|
 |
9cf8be |
if (sumLength >= maxLength)
|
|
 |
d0b5c0 |
{ outLongEnough = i < track.fixedSize(); break; }
|
|
 |
911124 |
}
|
|
 |
9f0c16 |
return sumWeight > TConsts::epsilon
|
|
 |
9cf8be |
? sumDeviation/sumWeight
|
|
 |
9cf8be |
: std::numeric_limits<double>::infinity();</double>
|
|
 |
911124 |
}
|
|
 |
911124 |
|
|
 |
911124 |
|
|
 |
911124 |
|
|
 |
911124 |
TGuidelineP
|
|
 |
9cf8be |
TGuideline::findBest(const TGuidelineList &guidelines, const TTrack &track, const TAffine &toScreen, bool &outLongEnough) {
|
|
 |
9cf8be |
outLongEnough = true;
|
|
 |
911124 |
double bestWeight = 0.0;
|
|
 |
911124 |
TGuidelineP best;
|
|
 |
911124 |
for(TGuidelineList::const_iterator i = guidelines.begin(); i != guidelines.end(); ++i) {
|
|
 |
9cf8be |
double weight = (*i)->calcTrackWeight(track, toScreen, outLongEnough);
|
|
 |
911124 |
if (!best || weight < bestWeight)
|
|
 |
911124 |
{ bestWeight = weight; best = *i; }
|
|
 |
911124 |
}
|
|
 |
911124 |
return best;
|
|
 |
911124 |
}
|
|
 |
911124 |
|
|
 |
911124 |
|
|
 |
911124 |
//************************************************************************
|
|
 |
249386 |
|
|
 |
249386 |
//************************************************************************
|
|
 |
249386 |
|
|
 |
7900ea |
TAssistantPoint::TAssistantPoint(const TStringId &name, const TPointD &defPosition):
|
|
 |
c5e805 |
name(name),
|
|
 |
7900ea |
defPosition(defPosition),
|
|
 |
c5e805 |
type(Circle),
|
|
 |
e48ced |
position(defPosition),
|
|
 |
249386 |
radius(10.0),
|
|
 |
c5e805 |
visible(true),
|
|
 |
249386 |
selected() { }
|
|
 |
249386 |
|
|
 |
249386 |
|
|
 |
249386 |
//************************************************************************
|
|
 |
4da757 |
|
|
 |
4da757 |
//************************************************************************
|
|
 |
4da757 |
|
|
 |
4da757 |
TMetaObjectHandler*
|
|
 |
4da757 |
TAssistantType::createHandler(TMetaObject &obj) const
|
|
 |
4da757 |
{ return createAssistant(obj); }
|
|
 |
4da757 |
|
|
 |
4da757 |
|
|
 |
4da757 |
//************************************************************************
|
|
 |
911124 |
|
|
 |
911124 |
//************************************************************************
|
|
 |
911124 |
|
|
 |
9cf8be |
TAssistant::TAssistant(TMetaObject &object):
|
|
 |
9cf8be |
TMetaObjectHandler(object),
|
|
 |
3bac66 |
m_idEnabled("enabled"),
|
|
 |
9cf8be |
m_idPoints("points"),
|
|
 |
9cf8be |
m_idX("x"),
|
|
 |
3bac66 |
m_idY("y"),
|
|
 |
c5e805 |
m_idMagnetism("magnetism"),
|
|
 |
c5e805 |
m_basePoint()
|
|
 |
3bac66 |
{
|
|
 |
4da757 |
addProperty( new TBoolProperty(m_idEnabled.str(), getEnabled()) );
|
|
 |
4da757 |
addProperty( new TDoubleProperty(m_idMagnetism.str(), 0.0, 1.0, getMagnetism()) );
|
|
 |
3bac66 |
}
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
c5e805 |
TAssistantPoint&
|
|
 |
c5e805 |
TAssistant::addPoint(
|
|
 |
c5e805 |
const TStringId &name,
|
|
 |
c5e805 |
TAssistantPoint::Type type,
|
|
 |
7900ea |
const TPointD &defPosition,
|
|
 |
c5e805 |
bool visible,
|
|
 |
c5e805 |
double radius )
|
|
 |
c5e805 |
{
|
|
 |
c5e805 |
assert(!m_points.count(name));
|
|
 |
c5e805 |
TAssistantPoint &p = m_points.insert(
|
|
 |
7900ea |
TAssistantPointMap::value_type(name, TAssistantPoint(name, defPosition)) ).first->second;
|
|
 |
7900ea |
m_pointsOrder.push_back(&p);
|
|
 |
c5e805 |
p.type = type;
|
|
 |
c5e805 |
p.radius = radius;
|
|
 |
c5e805 |
p.visible = visible;
|
|
 |
c5e805 |
if (!m_basePoint) m_basePoint = &p;
|
|
 |
c5e805 |
return p;
|
|
 |
c5e805 |
}
|
|
 |
c5e805 |
|
|
 |
c5e805 |
|
|
 |
c5e805 |
|
|
 |
c5e805 |
TAssistantPoint&
|
|
 |
c5e805 |
TAssistant::addPoint(
|
|
 |
c5e805 |
const TStringId &name,
|
|
 |
c5e805 |
TAssistantPoint::Type type,
|
|
 |
7900ea |
const TPointD &defPosition,
|
|
 |
c5e805 |
bool visible )
|
|
 |
7900ea |
{ return addPoint(name, type, defPosition, visible, 10.0); }
|
|
 |
c5e805 |
|
|
 |
c5e805 |
|
|
 |
c5e805 |
|
|
 |
c5e805 |
const TAssistantPoint&
|
|
 |
c5e805 |
TAssistant::getBasePoint() const
|
|
 |
c5e805 |
{ assert(m_basePoint); return *m_basePoint; }
|
|
 |
c5e805 |
|
|
 |
c5e805 |
|
|
 |
c5e805 |
|
|
 |
3bac66 |
void
|
|
 |
4da757 |
TAssistant::addProperty(TProperty *p)
|
|
 |
4da757 |
{ m_properties.add(p); }
|
|
 |
4da757 |
|
|
 |
4da757 |
|
|
 |
4da757 |
|
|
 |
4da757 |
void
|
|
 |
4da757 |
TAssistant::setTranslation(const TStringId &name, const QString &localName) const
|
|
 |
4da757 |
{ m_properties.getProperty(name)->setQStringName( localName ); }
|
|
 |
4da757 |
|
|
 |
4da757 |
|
|
 |
4da757 |
|
|
 |
4da757 |
void
|
|
 |
4da757 |
TAssistant::updateTranslation() const {
|
|
 |
4da757 |
setTranslation(m_idEnabled, tr("Enabled"));
|
|
 |
4da757 |
setTranslation(m_idMagnetism, tr("Magnetism"));
|
|
 |
3bac66 |
}
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
void
|
|
 |
3bac66 |
TAssistant::onSetDefaults() {
|
|
 |
3bac66 |
setEnabled(true);
|
|
 |
3bac66 |
setMagnetism(1.0);
|
|
 |
7900ea |
for(TAssistantPointMap::iterator i = m_points.begin(); i != m_points.end(); ++i)
|
|
 |
7900ea |
i->second.position = i->second.defPosition;
|
|
 |
7900ea |
fixPoints();
|
|
 |
7900ea |
fixData();
|
|
 |
3bac66 |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
c5e805 |
void
|
|
 |
c5e805 |
TAssistant::fixPoints()
|
|
 |
c5e805 |
{ onFixPoints(); }
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
b15438 |
bool
|
|
 |
7900ea |
TAssistant::move(const TPointD &position) {
|
|
 |
7900ea |
TPointD d = position - getBasePoint().position;
|
|
 |
b15438 |
if (d != TPointD()) {
|
|
 |
b15438 |
for(TAssistantPointMap::iterator i = m_points.begin(); i != m_points.end(); ++i)
|
|
 |
b15438 |
i->second.position += d;
|
|
 |
b15438 |
fixPoints();
|
|
 |
b15438 |
return true;
|
|
 |
b15438 |
}
|
|
 |
b15438 |
return false;
|
|
 |
7900ea |
}
|
|
 |
7900ea |
|
|
 |
7900ea |
|
|
 |
7900ea |
|
|
 |
b15438 |
bool
|
|
 |
c5e805 |
TAssistant::movePoint(const TStringId &name, const TPointD &position) {
|
|
 |
c5e805 |
TAssistantPointMap::iterator i = m_points.find(name);
|
|
 |
b15438 |
if (i != m_points.end() && i->second.position != position) {
|
|
 |
c5e805 |
onMovePoint(i->second, position);
|
|
 |
b15438 |
return true;
|
|
 |
b15438 |
}
|
|
 |
b15438 |
return false;
|
|
 |
c5e805 |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
c5e805 |
TAssistant::setPointSelection(const TStringId &name, bool selected) const {
|
|
 |
c5e805 |
if (const TAssistantPoint *p = findPoint(name))
|
|
 |
c5e805 |
p->selected = selected;
|
|
 |
c5e805 |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
c5e805 |
TAssistant::setAllPointsSelection(bool selected) const {
|
|
 |
c5e805 |
for(TAssistantPointMap::const_iterator i = points().begin(); i != points().end(); ++i)
|
|
 |
c5e805 |
i->second.selected = selected;
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
9cf8be |
TAssistant::onDataChanged(const TVariant &value) {
|
|
 |
9cf8be |
const TVariant& pointsData = data()[m_idPoints];
|
|
 |
9cf8be |
TVariantPathEntry entry;
|
|
 |
9cf8be |
|
|
 |
9cf8be |
if (&value == &data() || &value == &pointsData)
|
|
 |
9cf8be |
onAllDataChanged();
|
|
 |
9cf8be |
else
|
|
 |
c5e805 |
if (pointsData.getChildPathEntry(value, entry) && entry.isField()) {
|
|
 |
9cf8be |
const TVariant& pointData = pointsData[entry];
|
|
 |
9cf8be |
TPointD position = TPointD(
|
|
 |
9cf8be |
pointData[m_idX].getDouble(),
|
|
 |
9cf8be |
pointData[m_idY].getDouble() );
|
|
 |
c5e805 |
movePoint(entry.field(), position);
|
|
 |
3bac66 |
} else
|
|
 |
3bac66 |
if (data().getChildPathEntry(value, entry) && entry.isField()) {
|
|
 |
7900ea |
onDataFieldChanged(entry.field(), data()[entry.field()]);
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
7900ea |
TAssistant::onDataFieldChanged(const TStringId &name, const TVariant &value) {
|
|
 |
7900ea |
updateProperty(name, value);
|
|
 |
7900ea |
}
|
|
 |
7900ea |
|
|
 |
7900ea |
|
|
 |
7900ea |
|
|
 |
7900ea |
void
|
|
 |
9cf8be |
TAssistant::onAllDataChanged() {
|
|
 |
9cf8be |
const TVariant& pointsData = data()[m_idPoints];
|
|
 |
c5e805 |
for(TAssistantPointMap::iterator i = m_points.begin(); i != m_points.end(); ++i) {
|
|
 |
c5e805 |
const TVariant& pointData = pointsData[i->first];
|
|
 |
c5e805 |
i->second.position = TPointD(
|
|
 |
9cf8be |
pointData[m_idX].getDouble(),
|
|
 |
9cf8be |
pointData[m_idY].getDouble() );
|
|
 |
9cf8be |
}
|
|
 |
249386 |
fixPoints();
|
|
 |
3bac66 |
updateProperties();
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
9cf8be |
TAssistant::onFixPoints()
|
|
 |
9cf8be |
{ }
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
c5e805 |
TAssistant::onMovePoint(TAssistantPoint &point, const TPointD &position)
|
|
 |
c5e805 |
{ point.position = position; }
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
9cf8be |
TAssistant::onFixData() {
|
|
 |
9cf8be |
TVariant& pointsData = data()[m_idPoints];
|
|
 |
c5e805 |
for(TAssistantPointMap::const_iterator i = points().begin(); i != points().end(); ++i) {
|
|
 |
c5e805 |
TVariant& pointData = pointsData[i->first];
|
|
 |
c5e805 |
pointData[m_idX].setDouble( i->second.position.x );
|
|
 |
c5e805 |
pointData[m_idY].setDouble( i->second.position.y );
|
|
 |
9cf8be |
}
|
|
 |
3bac66 |
setMagnetism( std::max(0.0, std::min(1.0, getMagnetism())) );
|
|
 |
3bac66 |
}
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
void
|
|
 |
3bac66 |
TAssistant::updateProperties() {
|
|
 |
3bac66 |
const TVariantMap &map = data().getMap();
|
|
 |
3bac66 |
for(TVariantMap::const_iterator i = map.begin(); i != map.end(); ++i)
|
|
 |
3bac66 |
if (i->first != m_idPoints)
|
|
 |
3bac66 |
updateProperty(i->first, i->second);
|
|
 |
3bac66 |
}
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
void
|
|
 |
3bac66 |
TAssistant::updateProperty(const TStringId &name, const TVariant &value) {
|
|
 |
3bac66 |
TProperty *property = m_properties.getProperty(name);
|
|
 |
3bac66 |
if (!property)
|
|
 |
3bac66 |
return;
|
|
 |
3bac66 |
|
|
 |
3bac66 |
if (TBoolProperty *boolProperty = dynamic_cast<tboolproperty*>(property)) {</tboolproperty*>
|
|
 |
3bac66 |
boolProperty->setValue( value.getBool() );
|
|
 |
3bac66 |
} else
|
|
 |
3bac66 |
if (TDoubleProperty *doubleProperty = dynamic_cast<tdoubleproperty*>(property)) {</tdoubleproperty*>
|
|
 |
3bac66 |
doubleProperty->setValue( value.getDouble() );
|
|
 |
3bac66 |
} else
|
|
 |
3bac66 |
if (TStringProperty *stringProperty = dynamic_cast<tstringproperty*>(property)) {</tstringproperty*>
|
|
 |
3bac66 |
stringProperty->setValue( to_wstring(value.getString()) );
|
|
 |
3bac66 |
} else
|
|
 |
3bac66 |
if (TEnumProperty *enumProperty = dynamic_cast<tenumproperty*>(property)) {</tenumproperty*>
|
|
 |
3bac66 |
enumProperty->setValue( to_wstring(value.getString()) );
|
|
 |
3bac66 |
}
|
|
 |
3bac66 |
}
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
|
|
 |
3bac66 |
void
|
|
 |
3bac66 |
TAssistant::onPropertyChanged(const TStringId &name) {
|
|
 |
3bac66 |
TProperty *property = m_properties.getProperty(name);
|
|
 |
3bac66 |
if (!property)
|
|
 |
3bac66 |
return;
|
|
 |
3bac66 |
|
|
 |
3bac66 |
if (name == m_idPoints)
|
|
 |
3bac66 |
return;
|
|
 |
3bac66 |
|
|
 |
3bac66 |
if (TBoolProperty *boolProperty = dynamic_cast<tboolproperty*>(property)) {</tboolproperty*>
|
|
 |
3bac66 |
data()[name].setBool( boolProperty->getValue() );
|
|
 |
3bac66 |
} else
|
|
 |
3bac66 |
if (TDoubleProperty *doubleProperty = dynamic_cast<tdoubleproperty*>(property)) {</tdoubleproperty*>
|
|
 |
3bac66 |
data()[name].setDouble( doubleProperty->getValue() );
|
|
 |
3bac66 |
} else
|
|
 |
3bac66 |
if (TStringProperty *stringProperty = dynamic_cast<tstringproperty*>(property)) {</tstringproperty*>
|
|
 |
3bac66 |
data()[name].setString( to_string(stringProperty->getValue()) );
|
|
 |
3bac66 |
} else
|
|
 |
3bac66 |
if (TEnumProperty *enumProperty = dynamic_cast<tenumproperty*>(property)) {</tenumproperty*>
|
|
 |
3bac66 |
data()[name].setString( to_string(enumProperty->getValue()) );
|
|
 |
3bac66 |
}
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
c7854d |
double
|
|
 |
c7854d |
TAssistant::getDrawingAlpha(bool enabled) const
|
|
 |
c7854d |
{ return enabled && this->getEnabled() ? 0.5 : 0.25; }
|
|
 |
c7854d |
|
|
 |
c7854d |
|
|
 |
c7854d |
|
|
 |
c7854d |
double
|
|
 |
c7854d |
TAssistant::getDrawingGridAlpha() const
|
|
 |
c7854d |
{ return 0.2; }
|
|
 |
c7854d |
|
|
 |
c7854d |
|
|
 |
c7854d |
|
|
 |
9cf8be |
void
|
|
 |
c7854d |
TAssistant::drawSegment(const TPointD &p0, const TPointD &p1, double pixelSize, double alpha) const {
|
|
 |
c7854d |
double colorBlack[4] = { 0.0, 0.0, 0.0, alpha };
|
|
 |
c7854d |
double colorWhite[4] = { 1.0, 1.0, 1.0, alpha };
|
|
 |
4df9cd |
|
|
 |
4df9cd |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
 |
4df9cd |
tglEnableBlending();
|
|
 |
e48ced |
tglEnableLineSmooth(true, 1.0 * line_width_scale);
|
|
 |
4df9cd |
TPointD d = p1 - p0;
|
|
 |
4df9cd |
double k = norm2(d);
|
|
 |
4df9cd |
if (k > TConsts::epsilon*TConsts::epsilon) {
|
|
 |
e48ced |
k = 0.5*pixelSize*line_width_scale/sqrt(k);
|
|
 |
4df9cd |
d = TPointD(-k*d.y, k*d.x);
|
|
 |
4df9cd |
glColor4dv(colorWhite);
|
|
 |
4df9cd |
tglDrawSegment(p0 - d, p1 - d);
|
|
 |
4df9cd |
glColor4dv(colorBlack);
|
|
 |
4df9cd |
tglDrawSegment(p0 + d, p1 + d);
|
|
 |
4df9cd |
}
|
|
 |
4df9cd |
glPopAttrib();
|
|
 |
4df9cd |
}
|
|
 |
4df9cd |
|
|
 |
4df9cd |
|
|
 |
4df9cd |
|
|
 |
4df9cd |
void
|
|
 |
c7854d |
TAssistant::drawDot(const TPointD &p, double alpha) const {
|
|
 |
c7854d |
double colorBlack[4] = { 0.0, 0.0, 0.0, alpha };
|
|
 |
c7854d |
double colorWhite[4] = { 1.0, 1.0, 1.0, alpha };
|
|
 |
7900ea |
|
|
 |
7900ea |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
 |
7900ea |
tglEnableBlending();
|
|
 |
7900ea |
|
|
 |
7900ea |
glColor4dv(colorWhite);
|
|
 |
7c7225 |
tglEnablePointSmooth(6.0);
|
|
 |
7900ea |
glBegin(GL_POINTS);
|
|
 |
7900ea |
glVertex2d(p.x, p.y);
|
|
 |
7900ea |
glEnd();
|
|
 |
7900ea |
|
|
 |
7900ea |
glColor4dv(colorBlack);
|
|
 |
7c7225 |
tglEnablePointSmooth(3.0);
|
|
 |
7900ea |
glBegin(GL_POINTS);
|
|
 |
7900ea |
glVertex2d(p.x, p.y);
|
|
 |
7900ea |
glEnd();
|
|
 |
7900ea |
|
|
 |
7900ea |
glPopAttrib();
|
|
 |
7900ea |
}
|
|
 |
7900ea |
|
|
 |
7900ea |
|
|
 |
7900ea |
|
|
 |
7900ea |
void
|
|
 |
9cf8be |
TAssistant::drawPoint(const TAssistantPoint &point, double pixelSize) const {
|
|
 |
c5e805 |
if (!point.visible) return;
|
|
 |
c5e805 |
|
|
 |
249386 |
double radius = point.radius;
|
|
 |
9cf8be |
double crossSize = 1.2*radius;
|
|
 |
9cf8be |
|
|
 |
c7854d |
double alpha = 0.5;
|
|
 |
c7854d |
double colorBlack[4] = { 0.0, 0.0, 0.0, alpha };
|
|
 |
c7854d |
double colorGray[4] = { 0.5, 0.5, 0.5, alpha };
|
|
 |
c7854d |
double colorWhite[4] = { 1.0, 1.0, 1.0, alpha };
|
|
 |
e48ced |
double width = 1.5;
|
|
 |
9cf8be |
|
|
 |
9cf8be |
if (point.selected) {
|
|
 |
9cf8be |
colorBlack[2] = 1.0;
|
|
 |
9cf8be |
colorGray[2] = 1.0;
|
|
 |
249386 |
width = 2.0;
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
 |
9cf8be |
|
|
 |
249386 |
|
|
 |
9cf8be |
tglEnableBlending();
|
|
 |
9cf8be |
if (point.type == TAssistantPoint::CircleFill) {
|
|
 |
9cf8be |
glColor4dv(colorGray);
|
|
 |
9cf8be |
tglDrawDisk(point.position, radius*pixelSize);
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
249386 |
TPointD crossDx(pixelSize*crossSize, 0.0);
|
|
 |
249386 |
TPointD crossDy(0.0, pixelSize*crossSize);
|
|
 |
c7854d |
TPointD gridDx(pixelSize*radius, 0.0);
|
|
 |
c7854d |
TPointD gridDy(0.0, pixelSize*radius);
|
|
 |
9cf8be |
|
|
 |
249386 |
|
|
 |
e48ced |
tglEnableLineSmooth(true, 2.0*width*line_width_scale);
|
|
 |
249386 |
glColor4dv(colorWhite);
|
|
 |
249386 |
if (point.type == TAssistantPoint::CircleCross) {
|
|
 |
249386 |
tglDrawSegment(point.position - crossDx, point.position + crossDx);
|
|
 |
249386 |
tglDrawSegment(point.position - crossDy, point.position + crossDy);
|
|
 |
e48ced |
}
|
|
 |
249386 |
tglDrawCircle(point.position, radius*pixelSize);
|
|
 |
9cf8be |
|
|
 |
249386 |
|
|
 |
e48ced |
glLineWidth(width * line_width_scale);
|
|
 |
9cf8be |
glColor4dv(colorBlack);
|
|
 |
249386 |
if (point.type == TAssistantPoint::CircleCross) {
|
|
 |
249386 |
tglDrawSegment(point.position - crossDx, point.position + crossDx);
|
|
 |
249386 |
tglDrawSegment(point.position - crossDy, point.position + crossDy);
|
|
 |
249386 |
}
|
|
 |
249386 |
tglDrawCircle(point.position, radius*pixelSize);
|
|
 |
9cf8be |
|
|
 |
c7854d |
|
|
 |
c7854d |
switch(point.type) {
|
|
 |
c7854d |
case TAssistantPoint::CircleDoubleDots:
|
|
 |
c7854d |
drawDot(point.position - gridDx*0.5, alpha);
|
|
 |
c7854d |
drawDot(point.position + gridDx*0.5, alpha);
|
|
 |
c7854d |
drawDot(point.position - gridDy*0.5, alpha);
|
|
 |
c7854d |
drawDot(point.position + gridDy*0.5, alpha);
|
|
 |
c7854d |
//no break
|
|
 |
c7854d |
case TAssistantPoint::CircleDots:
|
|
 |
c7854d |
drawDot(point.position - gridDx, alpha);
|
|
 |
c7854d |
drawDot(point.position + gridDx, alpha);
|
|
 |
c7854d |
drawDot(point.position - gridDy, alpha);
|
|
 |
c7854d |
drawDot(point.position + gridDy, alpha);
|
|
 |
c7854d |
//no break
|
|
 |
c7854d |
case TAssistantPoint::Circle:
|
|
 |
c7854d |
drawDot(point.position, alpha);
|
|
 |
c7854d |
break;
|
|
 |
c7854d |
default:
|
|
 |
c7854d |
break;
|
|
 |
c7854d |
}
|
|
 |
c7854d |
|
|
 |
9cf8be |
glPopAttrib();
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
9cf8be |
TAssistant::getGuidelines(const TPointD &position, const TAffine &toTool, TGuidelineList &outGuidelines) const
|
|
 |
9cf8be |
{ }
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
8074a5 |
TAssistant::draw(TToolViewer *viewer, bool enabled) const
|
|
 |
9cf8be |
{ }
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9cf8be |
void
|
|
 |
9cf8be |
TAssistant::drawEdit(TToolViewer *viewer) const {
|
|
 |
9cf8be |
|
|
 |
4df9cd |
draw(viewer);
|
|
 |
9cf8be |
double pixelSize = sqrt(tglGetPixelSize2());
|
|
 |
c5e805 |
for(TAssistantPointMap::const_iterator i = points().begin(); i != points().end(); ++i)
|
|
 |
c5e805 |
drawPoint(i->second, pixelSize);
|
|
 |
9cf8be |
}
|
|
 |
9cf8be |
|
|
 |
9cf8be |
|
|
 |
9a49d4 |
|
|
 |
9a49d4 |
bool
|
|
 |
9a49d4 |
TAssistant::calcPerspectiveStep(
|
|
 |
9a49d4 |
double minStep,
|
|
 |
9a49d4 |
double minX,
|
|
 |
9a49d4 |
double maxX,
|
|
 |
9a49d4 |
double x0,
|
|
 |
9a49d4 |
double x1,
|
|
 |
9a49d4 |
double x2,
|
|
 |
9a49d4 |
double &outK,
|
|
 |
9a49d4 |
double &outMin,
|
|
 |
9a49d4 |
double &outMax )
|
|
 |
9a49d4 |
{
|
|
 |
9a49d4 |
outK = outMin = outMax = 0.0;
|
|
 |
9a49d4 |
|
|
 |
9a49d4 |
double dx1 = x1 - x0;
|
|
 |
9a49d4 |
double dx2 = x2 - x0;
|
|
 |
9a49d4 |
if (fabs(dx1) <= TConsts::epsilon) return false;
|
|
 |
9a49d4 |
if (fabs(dx2) <= TConsts::epsilon) return false;
|
|
 |
9a49d4 |
if ((dx1 < 0.0) != (dx2 < 0.0)) dx2 = -dx2;
|
|
 |
9a49d4 |
if (fabs(dx2 - dx1) <= minStep) return false;
|
|
 |
9a49d4 |
if (fabs(dx2) < fabs(dx1)) std::swap(dx1, dx2);
|
|
 |
9a49d4 |
|
|
 |
9a49d4 |
if (x0 <= minX + TConsts::epsilon && dx1 < 0.0) return false;
|
|
 |
9a49d4 |
if (x0 >= maxX - TConsts::epsilon && dx1 > 0.0) return false;
|
|
 |
9a49d4 |
|
|
 |
9a49d4 |
outK = dx2/dx1;
|
|
 |
9a49d4 |
double minI = log(minStep/fabs(dx1*(1.0 - 1.0/outK)))/log(outK);
|
|
 |
9a49d4 |
outMin = dx1*pow(outK, floor(minI - TConsts::epsilon));
|
|
 |
9a49d4 |
if (fabs(outMin) < TConsts::epsilon) return false;
|
|
 |
9a49d4 |
outMax = (dx1 > 0.0 ? maxX : minX) - x0;
|
|
 |
9a49d4 |
return true;
|
|
 |
9a49d4 |
}
|