Skip to content

Commit

Permalink
Implement automatic scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
WandererFan authored and wwmayer committed Aug 16, 2016
1 parent fa57b7a commit cf90d69
Show file tree
Hide file tree
Showing 16 changed files with 198 additions and 78 deletions.
8 changes: 7 additions & 1 deletion src/Mod/TechDraw/App/DrawPage.cpp
Expand Up @@ -244,11 +244,17 @@ int DrawPage::addView(App::DocumentObject *docObj)
view->Y.setValue(getPageHeight()/2.0);
}

//add view to list
const std::vector<App::DocumentObject *> currViews = Views.getValues();
std::vector<App::DocumentObject *> newViews(currViews);
newViews.push_back(docObj);
Views.setValues(newViews);
Views.touch();

//check if View fits on Page
if ( !view->checkFit(this) ) {
Base::Console().Warning("%s is larger than page. Will be scaled.\n",view->getNameInDocument());
view->ScaleType.setValue("Automatic");
}

return Views.getSize();
}
Expand Down
63 changes: 48 additions & 15 deletions src/Mod/TechDraw/App/DrawProjGroup.cpp
Expand Up @@ -149,7 +149,8 @@ double DrawProjGroup::calculateAutomaticScale() const
double scale_x = availableX / width;
double scale_y = availableY / height;

float working_scale = std::min(scale_x, scale_y);
double fudgeFactor = 0.90;
float working_scale = fudgeFactor * std::min(scale_x, scale_y);

//which gives the largest scale for which the min_space requirements can be met, but we want a 'sensible' scale, rather than 0.28457239...
//eg if working_scale = 0.115, then we want to use 0.1, similarly 7.65 -> 5, and 76.5 -> 50
Expand All @@ -168,6 +169,15 @@ double DrawProjGroup::calculateAutomaticScale() const
return valid_scales[(exponent >= 0)][i] * pow(10, exponent);
}

QRectF DrawProjGroup::getRect() const
{
DrawProjGroupItem *viewPtrs[10];
arrangeViewPointers(viewPtrs);
double width, height;
minimumBbViews(viewPtrs, width, height); //min space for 1:1 drawing
return QRectF(0,0,Scale.getValue() * width,Scale.getValue() * height);
}

void DrawProjGroup::minimumBbViews(DrawProjGroupItem *viewPtrs[10],
double &width, double &height) const
{
Expand Down Expand Up @@ -543,29 +553,52 @@ void DrawProjGroup::setFrontViewOrientation(const Base::Matrix4D &newMat)

App::DocumentObjectExecReturn *DrawProjGroup::execute(void)
{
if (ScaleType.isValue("Automatic")) {

//Recalculate scale
double autoScale = calculateAutomaticScale();

if(std::abs(Scale.getValue() - autoScale) > FLT_EPSILON) {
// Set this Scale
Scale.setValue(autoScale);
//if group hasn't been added to page yet, can't scale or distribute projItems
TechDraw::DrawPage *page = getPage();
if (!page) {
return DrawViewCollection::execute();
}

if (ScaleType.isValue("Automatic")) {
//Recalculate scale if Group is too big
if (!checkFit(page)) {
double newScale = calculateAutomaticScale();
if(std::abs(Scale.getValue() - newScale) > FLT_EPSILON) {
Scale.setValue(newScale);
//Rebuild the DPGI's
for( const auto it : Views.getValues() ) {
auto view( dynamic_cast<DrawProjGroupItem *>(it) );
if( view ) {
view->ScaleType.setValue("Custom");
view->Scale.setValue(newScale); //not sure we have to set scale here. DVP will do it based on ScaleType
view->Scale.setStatus(App::Property::ReadOnly,true);
//view->touch();
}
}
resetPositions();
}
}
} else if (ScaleType.isValue("Document")) {
double docScale = page->Scale.getValue();
if(std::abs(Scale.getValue() - docScale) > FLT_EPSILON) {
Scale.setValue(docScale);
//Rebuild the DPGI's
for( const auto it : Views.getValues() ) {
auto view( dynamic_cast<DrawProjGroupItem *>(it) );
if( view ) {
view->ScaleType.setValue("Custom");
view->Scale.setValue(autoScale);
const std::vector<App::DocumentObject *> &views = Views.getValues();
for(std::vector<App::DocumentObject *>::const_iterator it = views.begin(); it != views.end(); ++it) {
App::DocumentObject *docObj = *it;
if(docObj->getTypeId().isDerivedFrom(DrawProjGroupItem::getClassTypeId())) {
DrawProjGroupItem *view = dynamic_cast<DrawProjGroupItem *>(*it);
view->ScaleType.setValue("Document");
view->Scale.setValue(docScale);
view->Scale.setStatus(App::Property::ReadOnly,true);
view->touch();
//view->touch();
}
}
resetPositions();
}
}


// recalculate positions for children
if (Views.getSize()) {
distributeProjections();
Expand Down
2 changes: 2 additions & 0 deletions src/Mod/TechDraw/App/DrawProjGroup.h
Expand Up @@ -23,6 +23,7 @@
#ifndef _TECHDRAW_FEATUREVIEWGROUP_H_
#define _TECHDRAW_FEATUREVIEWGROUP_H_

# include <QRectF>
#include <App/DocumentObject.h>
#include <App/PropertyStandard.h>

Expand Down Expand Up @@ -63,6 +64,7 @@ class TechDrawExport DrawProjGroup : public TechDraw::DrawViewCollection

Base::BoundBox3d getBoundingBox() const;
double calculateAutomaticScale() const;
virtual QRectF getRect(void) const;

/// Check if container has a view of a specific type
bool hasProjection(const char *viewProjType) const;
Expand Down
20 changes: 1 addition & 19 deletions src/Mod/TechDraw/App/DrawProjGroupItem.cpp
Expand Up @@ -56,17 +56,9 @@ DrawProjGroupItem::DrawProjGroupItem(void)
Type.setEnums(TypeEnums);
ADD_PROPERTY(Type, ((long)0));

// Set Hidden
//Direction.StatusBits.set(3);
//projection group controls these
Direction.setStatus(App::Property::Hidden,true);

// Set Hidden
//XAxisDirection.StatusBits.set(3);
XAxisDirection.setStatus(App::Property::Hidden,true);

// Scale and ScaleType are Readonly
//Scale.StatusBits.set(2);
//ScaleType.StatusBits.set(2);
Scale.setStatus(App::Property::ReadOnly,true);
ScaleType.setStatus(App::Property::ReadOnly,true);
}
Expand Down Expand Up @@ -101,16 +93,6 @@ void DrawProjGroupItem::onDocumentRestored()
execute();
}

/*
//TODO: Perhaps we don't need this anymore?
App::DocumentObjectExecReturn *DrawProjGroupItem::execute(void)
{
if(Type.isTouched()) {
Type.purgeTouched();
}
return TechDraw::DrawViewPart::execute();
}*/

PyObject *DrawProjGroupItem::getPyObject(void)
{
Expand Down
83 changes: 50 additions & 33 deletions src/Mod/TechDraw/App/DrawView.cpp
Expand Up @@ -79,69 +79,63 @@ DrawView::~DrawView()
{
}

App::DocumentObjectExecReturn *DrawView::recompute(void)
{
try {
return App::DocumentObject::recompute();
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
App::DocumentObjectExecReturn* ret = new App::DocumentObjectExecReturn(e->GetMessageString());
if (ret->Why.empty()) ret->Why = "Unknown OCC exception";
return ret;
}
}

App::DocumentObjectExecReturn *DrawView::execute(void)
{
//right way to handle this? can't do it at creation since don't have a parent.
if (ScaleType.isValue("Document")) {
TechDraw::DrawPage *page = findParentPage();
if(page) {
TechDraw::DrawPage *page = findParentPage();
if(page) {
if (ScaleType.isValue("Document")) {
if(std::abs(page->Scale.getValue() - Scale.getValue()) > FLT_EPSILON) {
Scale.setValue(page->Scale.getValue());
Scale.touch();
}
} else if (ScaleType.isValue("Automatic")) {
//check fit. if too big, rescale
if (!checkFit(page)) {
double newScale = autoScale(page->getPageWidth(),page->getPageHeight());
if(std::abs(newScale - Scale.getValue()) > FLT_EPSILON) { //stops onChanged/execute loop
Scale.setValue(newScale);
}
}
}
}

return App::DocumentObject::execute();
}

/// get called by the container when a Property was changed
void DrawView::onChanged(const App::Property* prop)
{
if (!isRestoring()) {
if (prop == &ScaleType ||
prop == &Scale) {
if (prop == &Scale) {
execute();
} else if (prop == &ScaleType) {
if (ScaleType.isValue("Document")) {
TechDraw::DrawPage *page = findParentPage();
if(page) {
if(std::abs(page->Scale.getValue() - Scale.getValue()) > FLT_EPSILON) {
Scale.setValue(page->Scale.getValue()); // Reset scale from page
Scale.touch();
}
}
Scale.setStatus(App::Property::ReadOnly,true);
App::GetApplication().signalChangePropertyEditor(Scale);
} else if ( ScaleType.isValue("Custom") ) {
Scale.setStatus(App::Property::ReadOnly,false);
App::GetApplication().signalChangePropertyEditor(Scale);
} else if ( ScaleType.isValue("Automatic") ) {
Scale.setStatus(App::Property::ReadOnly,true);
App::GetApplication().signalChangePropertyEditor(Scale);
}
//TODO else if (ScaleType.isValue("Automatic"))...
DrawView::execute();
execute();
} else if (prop == &X ||
prop == &Y) {
setAutoPos(false);
DrawView::execute();
execute();
} else if (prop == &Rotation) {
DrawView::execute();
execute();
}
}

App::DocumentObject::onChanged(prop);
}

////you must override this in derived class
QRectF DrawView::getRect() const
{
QRectF result(0,0,1,1);
return result;
}

void DrawView::onDocumentRestored()
{
// Rebuild the view
Expand Down Expand Up @@ -182,6 +176,29 @@ bool DrawView::isInClip()
return false;
}

double DrawView::autoScale(double w, double h) const
{
double fudgeFactor = 0.90;
QRectF viewBox = getRect();
double xScale = w/viewBox.width();
double yScale = h/viewBox.height();
//find a standard scale that's close? 1:2, 1:10, 1:100...?
double newScale = fudgeFactor * std::min(xScale,yScale);
return newScale;
}

//!check if View fits on Page
bool DrawView::checkFit(TechDraw::DrawPage* p) const
{
bool result = true;
QRectF viewBox = getRect();
if ( (viewBox.width() > p->getPageWidth()) ||
(viewBox.height() > p->getPageHeight()) ) {
result = false;
}
return result;
}

PyObject *DrawView::getPyObject(void)
{
if (PythonObject.is(Py::_None())) {
Expand Down
6 changes: 5 additions & 1 deletion src/Mod/TechDraw/App/DrawView.h
Expand Up @@ -23,6 +23,8 @@
#ifndef _DrawView_h_
#define _DrawView_h_

#include <QRectF>

#include <App/DocumentObject.h>
#include <App/PropertyStandard.h>
#include <App/PropertyGeo.h>
Expand Down Expand Up @@ -54,7 +56,6 @@ class TechDrawExport DrawView : public App::DocumentObject
/** @name methods overide Feature */
//@{
/// recalculate the Feature
virtual App::DocumentObjectExecReturn *recompute(void);
virtual App::DocumentObjectExecReturn *execute(void);
virtual void onDocumentRestored();
//@}
Expand All @@ -71,6 +72,9 @@ class TechDrawExport DrawView : public App::DocumentObject
DrawPage* findParentPage() const;
bool allowAutoPos() {return autoPos;}; //sb in DPGI??
void setAutoPos(bool state) {autoPos = state;};
virtual QRectF getRect() const; //must be overridden by derived class
virtual double autoScale(double w, double h) const;
virtual bool checkFit(DrawPage*) const;

protected:
void onChanged(const App::Property* prop);
Expand Down
19 changes: 17 additions & 2 deletions src/Mod/TechDraw/App/DrawViewAnnotation.cpp
Expand Up @@ -73,8 +73,6 @@ DrawViewAnnotation::DrawViewAnnotation(void)
TextStyle.setEnums(TextStyleEnums);
ADD_PROPERTY(TextStyle, ((long)0));

//Scale.StatusBits.set(3); //hide scale. n/a for Annotation
//ScaleType.StatusBits.set(3);
Scale.setStatus(App::Property::Hidden,true);
ScaleType.setStatus(App::Property::Hidden,true);
}
Expand Down Expand Up @@ -104,6 +102,23 @@ void DrawViewAnnotation::onChanged(const App::Property* prop)
TechDraw::DrawView::onChanged(prop);
}

QRectF DrawViewAnnotation::getRect() const
{
QRectF result;
double tSize = TextSize.getValue();
int lines = Text.getValues().size();
int chars = 1;
for (auto& l:Text.getValues()) {
if ((int)l.size() > chars) {
chars = (int)l.size();
}
}
int w = chars * std::max(1,(int)tSize);
int h = lines * std::max(1,(int)tSize);
result = QRectF(0,0,Scale.getValue() * w,Scale.getValue() * h);
return result;
}

App::DocumentObjectExecReturn *DrawViewAnnotation::execute(void)
{
return TechDraw::DrawView::execute();
Expand Down
5 changes: 2 additions & 3 deletions src/Mod/TechDraw/App/DrawViewAnnotation.h
Expand Up @@ -27,7 +27,6 @@
#ifndef _DrawViewAnnotation_h_
#define _DrawViewAnnotation_h_


#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <App/PropertyStandard.h>
Expand All @@ -39,8 +38,6 @@ namespace TechDraw
{


/** Base class of all View Features in the drawing module
*/
class TechDrawExport DrawViewAnnotation : public TechDraw::DrawView
{
PROPERTY_HEADER(TechDraw::DrawViewAnnotation);
Expand All @@ -58,6 +55,8 @@ class TechDrawExport DrawViewAnnotation : public TechDraw::DrawView
App::PropertyEnumeration TextStyle; // Plain,Bold,Italic,Bold-Italic
App::PropertyFloat MaxWidth;

virtual QRectF getRect() const;

/** @name methods overide Feature */
//@{
/// recalculate the Feature
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/TechDraw/App/DrawViewClip.h
Expand Up @@ -25,7 +25,6 @@
#ifndef _DrawViewClip_h_
#define _DrawViewClip_h_


#include <App/DocumentObject.h>
#include <App/DocumentObjectGroup.h>
#include <App/PropertyLinks.h>
Expand Down Expand Up @@ -71,6 +70,7 @@ class TechDrawExport DrawViewClip: public TechDraw::DrawView

std::vector<std::string> getChildViewNames();
bool isViewInClip(App::DocumentObject* view);
virtual QRectF getRect(void) const { return QRectF(0,0,Width.getValue(),Height.getValue()); }


protected:
Expand Down

0 comments on commit cf90d69

Please sign in to comment.